psemek/libs/util/source/executable_path.cpp

37 lines
899 B
C++

#include <psemek/util/executable_path.hpp>
#include <psemek/util/to_string.hpp>
#include <psemek/util/exception.hpp>
#ifdef _WIN32
#include <libloaderapi.h>
#include <errhandlingapi.h>
#include <winerror.h>
#endif
namespace psemek::util
{
std::filesystem::path executable_path()
{
#if defined _WIN32
std::wstring result(256, '\0');
while (true)
{
GetModuleFileNameW(NULL, result.data(), result.size());
auto error = GetLastError();
if (error == ERROR_SUCCESS)
break;
else if (error == ERROR_INSUFFICIENT_BUFFER)
result.resize(result.size() * 2);
else
throw exception(util::to_string("failed to retrieve executable path: ", std::hex, error));
}
return std::filesystem::path(result);
#elif defined __linux__
return std::filesystem::canonical("/proc/self/exe");
#else
throw exception("executable_path() is not implemented for this platform");
#endif
}
}