The key is to use (passing as a module descriptor to access the current EXE process) and then call (or if you do not need versions of Windows prior to Windows 8) to remove the spec file from the path. GetModuleFileName()nullptr PathRemoveFileSpec()PathCchRemoveFileSpec()
PathRemoveFileSpec(), Shlwapi.lib, MSDN.
. :
#include <iostream> // For console output
#include <exception> // For std::exception
#include <stdexcept> // For std::runtime_error
#include <string> // For std::wstring
#include <Windows.h> // For Win32 SDK
#include <Shlwapi.h> // For PathRemoveFileSpec()
#pragma comment(lib, "Shlwapi.lib")
class win32_error : public std::runtime_error
{
public:
win32_error(const char * msg, DWORD error)
: std::runtime_error(msg)
, _error(error)
{ }
DWORD error() const
{
return _error;
}
private:
DWORD _error;
};
std::wstring GetPathOfExe()
{
wchar_t filename[MAX_PATH];
DWORD result = ::GetModuleFileName(
nullptr,
filename,
_countof(filename)
);
if (result == 0)
{
const DWORD error = ::GetLastError();
throw win32_error("Error in getting module filename.",
error);
}
::PathRemoveFileSpec(filename);
return filename;
}
int main()
{
try
{
std::wcout << "Path for current EXE:\n"
<< GetPathOfExe()
<< std::endl;
}
catch (const win32_error & e)
{
std::cerr << "\n*** ERROR: " << e.what()
<< " (error code: " << e.error() << ")"
<< std::endl;
}
catch (const std::exception& e)
{
std::cerr << "\n*** ERROR: " << e.what() << std::endl;
}
}
:
C:\Temp\CppTests>cl /EHsc /W4 /nologo /DUNICODE /D_UNICODE get_exe_path.cpp
get_exe_path.cpp
C:\Temp\CppTests>get_exe_path.exe
Path for current EXE:
C:\Temp\CppTests
PS
, , Unicode FindFirtFile() (.. FindFirstFileW(), LPCWSTR, const wchar_t*), ANSI/MBCS (.. char*).
Unicode UTF-16 wchar_t* Windows ++: , API Win32 Unicode.
, , ++, (, std::wstring Unicode UTF-16 Microsoft Visual ++) C- . API ( Win32 API C), std::wstring.