Windows 用 GetModuleFileNameA 获取可执行文件绝对路径,Linux 用 readlink("/proc/self/exe") 读取符号链接,两者均需截断至目录部分;禁用 getcwd() 和不可靠的 argv[0]。

在 Windows 和 Linux 上用 C++ 获取当前程序运行路径,不能依赖 getcwd()(它返回的是进程启动时的工作目录,不是程序所在目录),必须通过系统 API 读取可执行文件自身的路径并做截断。
Windows 下用 GetModuleFileNameA 获取 exe 路径
Windows 提供了稳定可靠的 API:GetModuleFileNameA(或宽字符版 GetModuleFileNameW),传入 NULL 或 HMODULE(0) 即可获取当前进程主模块(即 exe)的完整路径。
- 必须包含
<windows.h></windows.h> - 缓冲区大小建议至少
MAX_PATH(260),但更稳妥可用MAX_PATH + 1或动态分配 - 返回值为实际写入长度,为 0 表示失败,需检查
GetLastError() - 路径是绝对路径,含盘符和
.exe后缀,需手动截断到目录部分(用find_last_of('\'))
char path[MAX_PATH];
if (GetModuleFileNameA(NULL, path, MAX_PATH) == 0) {
// 处理错误
}
std::string exe_dir = std::string(path, path + strlen(path));
size_t last_sep = exe_dir.find_last_of('\');
if (last_sep != std::string::npos) {
exe_dir = exe_dir.substr(0, last_sep);
}
Linux 下用 /proc/self/exe 符号链接解析
Linux 没有等价的 API,但可通过读取 /proc/self/exe 这个符号链接获得可执行文件的绝对路径——这是最通用、无需 argv[0] 参与、且能正确处理 symlink 的方式。
- 必须包含
<unistd.h></unistd.h>和<limits.h></limits.h> - 用
readlink("/proc/self/exe", buf, sizeof(buf)-1),返回值是实际字节数,不自动加
