I know this question has been asked before but I still haven\'t seen a satisfactory answer, or a definitive \"no, this cannot be done\", so I\'ll ask again!
All I wa
For Windows, you have the problem of how to strip the executable from the result of GetModuleFileName()
. The Windows API call PathRemoveFileSpec()
that Nate used for that purpose in his answer changed between Windows 8 and its predecessors. So how to remain compatible with both and safe? Luckily, there's C++17 (or Boost, if you're using an older compiler). I do this:
#include
#include
#include
namespace fs = std::experimental::filesystem;
// We could use fs::path as return type, but if you're not aware of
// std::experimental::filesystem, you probably handle filenames
// as strings anyway in the remainder of your code. I'm on Japanese
// Windows, so wide chars are a must.
std::wstring getDirectoryWithCurrentExecutable()
{
int size = 256;
std::vector charBuffer;
// Let's be safe, and find the right buffer size programmatically.
do {
size *= 2;
charBuffer.resize(size);
// Resize until filename fits. GetModuleFileNameW returns the
// number of characters written to the buffer, so if the
// return value is smaller than the size of the buffer, it was
// large enough.
} while (GetModuleFileNameW(NULL, charBuffer.data(), size) == size);
// Typically: c:/program files (x86)/something/foo/bar/exe/files/win64/baz.exe
// (Note that windows supports forward and backward slashes as path
// separators, so you have to be careful when searching through a path
// manually.)
// Let's extract the interesting part:
fs::path path(charBuffer.data()); // Contains the full path including .exe
return path.remove_filename() // Extract the directory ...
.w_str(); // ... and convert to a string.
}