Ответ 1
Используйте GetModuleHandle и GetModuleFileName, чтобы узнать, где exe работает от.
HMODULE hModule = GetModuleHandleW(NULL);
WCHAR path[MAX_PATH];
GetModuleFileNameW(hModule, path, MAX_PATH);
Затем отделите имя exe от пути.
Мне нужно получить доступ к некоторым файлам с помощью fstream
в моем приложении на С++ в Windows. Эти файлы находятся в подпапках папки, в которой находится мой exe файл.
Используйте GetModuleHandle и GetModuleFileName, чтобы узнать, где exe работает от.
HMODULE hModule = GetModuleHandleW(NULL);
WCHAR path[MAX_PATH];
GetModuleFileNameW(hModule, path, MAX_PATH);
Затем отделите имя exe от пути.
GetThisPath.h
/// dest is expected to be MAX_PATH in length.
/// returns dest
/// TCHAR dest[MAX_PATH];
/// GetThisPath(dest, MAX_PATH);
TCHAR* GetThisPath(TCHAR* dest, size_t destSize);
GetThisPath.cpp
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
TCHAR* GetThisPath(TCHAR* dest, size_t destSize)
{
if (!dest) return NULL;
if (MAX_PATH > destSize) return NULL;
DWORD length = GetModuleFileName( NULL, dest, destSize );
PathRemoveFileSpec(dest);
return dest;
}
mainProgram.cpp
TCHAR dest[MAX_PATH];
GetThisPath(dest, MAX_PATH);
Обновление: PathRemoveFileSpec
устарел в Windows 8. Однако замена PathCchRemoveFileSpec
, доступен только в Windows 8+. (Спасибо @askalee за комментарий)
Я думаю, что этот код ниже может работать, но я оставляю выше код до тех пор, пока не будет проверен нижний код. На данный момент у меня нет компилятора, чтобы проверить это. Если у вас есть шанс протестировать этот код, напишите комментарий, если этот ниже код работал и на какой операционной системе вы протестировали. Благодарю!
GetThisPath.h
/// dest is expected to be MAX_PATH in length.
/// returns dest
/// TCHAR dest[MAX_PATH];
/// GetThisPath(dest, MAX_PATH);
TCHAR* GetThisPath(TCHAR* dest, size_t destSize);
GetThisPath.cpp
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
TCHAR* GetThisPath(TCHAR* dest, size_t destSize)
{
if (!dest) return NULL;
DWORD length = GetModuleFileName( NULL, dest, destSize );
#if (NTDDI_VERSION >= NTDDI_WIN8)
PathCchRemoveFileSpec(dest, destSize);
#else
if (MAX_PATH > destSize) return NULL;
PathRemoveFileSpec(dest);
#endif
return dest;
}
mainProgram.cpp
TCHAR dest[MAX_PATH];
GetThisPath(dest, MAX_PATH);
По умолчанию каталогом, из которого запускается exe, должно быть начальное местоположение. Поэтому открытие файла во вложенной папке должно быть таким же простым, как
fstream infile;
infile.open(".\\subfolder\\filename.ext");
из вашей программы.
Однако нет никакого реального способа для ГАРАНТИИ, это всегда будет работать, если вы не используете фреймворк, который обертывает необходимые функции (я бы посмотрел на boost) или напрямую использовал API Windows, например GetModuleFileName
(как предложено)