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
char exePath[512];
CString strexePath;
GetModuleFileName(NULL,exePath,512);
strexePath.Format("%s",exePath);
strexePath = strexePath.Mid(0,strexePath.ReverseFind('\\'));
QT provides this with OS abstraction as QCoreApplication::applicationDirPath()
For Windows you can use GetModuleFilename().
For Linux see BinReloc (old, defunct URL) mirror of BinReloc in datenwolf's GitHub repositories.
C++17, windows, unicode, using filesystem new api:
#include "..\Project.h"
#include <filesystem>
using namespace std;
using namespace filesystem;
int wmain(int argc, wchar_t** argv)
{
auto dir = weakly_canonical(path(argv[0])).parent_path();
printf("%S", dir.c_str());
return 0;
}
Suspect this solution should be portable, but don't know how unicode is implemented on other OS's.
weakly_canonical is needed only if you use as Output Directory upper folder references ('..') to simplify path. If you don't use it - remove it.
If you're operating from dynamic link library (.dll /.so), then you might not have argv, then you can consider following solution:
application.h:
#pragma once
//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std {
namespace filesystem = experimental::filesystem;
}
#endif
std::filesystem::path getexepath();
application.cpp:
#include "application.h"
#ifdef _WIN32
#include <windows.h> //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h> //readlink
#endif
std::filesystem::path getexepath()
{
#ifdef _WIN32
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, path, MAX_PATH);
return path;
#else
char result[PATH_MAX];
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
return std::string(result, (count > 0) ? count : 0);
#endif
}
As others mentioned, argv[0]
is quite a nice solution, provided that the platform actually passes the executable path, which is surely not less probable than the OS being Windows (where WinAPI can help find the executable path). If you want to strip the string to only include the path to the directory where the executable resides, then using that path to find other application files (like game assets if your program is a game) is perfectly fine, since opening files is relative to the working directory, or, if provided, the root.