获取当前进程的可执行文件的绝对路径

本文介绍如何在Windows和Linux系统中获取程序的绝对路径。Windows下使用GetModuleFileNameA()函数并替换路径中的反斜杠。Linux中利用readlink读取特殊文件/proc/self/exe的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

windows下可以使用GetModuleFileNameA()函数获取绝对路径,不过文件路径中的反斜杠需要进行替换。

linux系统中有个符号链接:/proc/self/exe 它代表当前程序,所以可以用readlink读取它的源路径就可以获取当前程序的绝对路径。
readlink的man注释
Prolog
This manual page is part of the POSIX Programmer’s Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on Linux.

Name
readlink - read the contents of a symbolic link

Synopsis

#include <unistd.h>
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);

Description
The readlink() function shall place the contents of the symbolic link referred to by path in the buffer buf which has size bufsize. If the number of bytes in the symbolic link is less than bufsize, the contents of the remainder of buf are unspecified. If the buf argument is not large enough to contain the link content, the first bufsize bytes shall be placed in buf.
If the value of bufsize is greater than {SSIZE_MAX}, the result is implementation-defined.

Return Value
Upon successful completion, readlink() shall return the count of bytes placed in the buffer. Otherwise, it shall return a value of -1, leave the buffer unchanged, and set errno to indicate the error.

Errors
The readlink() function shall fail if:
EACCES Search permission is denied for a component of the path prefix of path. EINVAL The path argument names a file that is not a symbolic link. EIO An I/O error occurred while reading from the file system. ELOOP A loop exists in symbolic links encountered during resolution of the path argument. ENAMETOOLONG The length of the path argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}. ENOENT A component of path does not name an existing file or path is an empty string. ENOTDIR A component of the path prefix is not a directory.
The readlink() function may fail if:
EACCES Read permission is denied for the directory. ELOOP More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument. ENAMETOOLONG As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded {PATH_MAX}.
The following sections are informative.

示例代码:

#include <unistd.h>
#include <stdio.h>

int main(int argc , char* argv[])
{
    char buf[1024] = { 0 };
    int n;

    n = (int)readlink("/proc/self/exe" , buf , sizeof(buf) - 1);
    if(n < 0)
    {
        printf("error: %d",n);
    }
    buf[n]='\0';
    return 0;
}
### C++ 中获取当前可执行文件路径的方法 在 C++ 编程中,获取当前可执行文件的路径可以通过多种方法实现。以下是几种常见的技术: #### 使用 `/proc/self/exe` 的方法 在 Linux 平台上,可以利用操作系统提供的特殊符号链接 `/proc/self/exe` 来获取当前可执行文件的具体位置。这种方法被认为是最可靠和最简单的解决方案之一[^1]。 ```cpp #include <unistd.h> #include <limits.h> std::string getExecutablePath() { char path[PATH_MAX]; ssize_t count = readlink("/proc/self/exe", path, sizeof(path) - 1); if (count != -1) { path[count] = '\0'; return std::string(path); } return ""; } ``` 此代码片段展示了如何通过 `readlink()` 函数解析 `/proc/self/exe` 链接并返回完整的可执行文件路径。 --- #### 利用 `argv[0]` 另一种常见的方式是从程序启动参数中的 `argv[0]` 提取可执行文件名或路径。需要注意的是,这种方式可能仅提供相对路径或者不带任何路径信息的情况,因此其可靠性较低。 ```cpp #include <iostream> #include <cstdlib> void printExecutableName(char * argv[]) { std::cout << "Executable name/path: " << argv[0] << std::endl; } int main(int argc, char * argv[]) { printExecutableName(argv); return EXIT_SUCCESS; } ``` 上述例子演示了如何直接打印传入到主函数的命令行参数的第一个值作为可执行文件名称/路径。 --- #### 调用 `getcwd()` 获取工作目录 虽然严格来说这不是一种获得 **可执行文件** 路径的办法,但是有时候我们需要知道进程的工作目录以便进一步处理其他资源定位逻辑。这里给出基于 POSIX 标准库的一个示例来展示怎样取得当前工作的绝对路径[^2]: ```cpp #include <stdio.h> #include <stdlib.h> #include <errno.h> char* getCurrentWorkingDirectory() { char* buffer = nullptr; size_t size = 0; errno = 0; buffer = getcwd(nullptr, 0); // Let the system allocate memory automatically. if (!buffer && errno != 0){ perror("Error retrieving current working directory"); exit(EXIT_FAILURE); } printf("Current Working Directory:%s\n", buffer); free(buffer); // Free allocated resources after use. return buffer; } ``` 注意该版本会自动分配足够的空间存储结果字符串,并且记得释放动态申请的空间以防泄漏。 --- #### Windows 特定 API `_pgmptr` 如果目标平台是 Microsoft Windows,则可以直接访问全局变量 `_pgmptr` ,它包含了指向可执行映像全限定路径的指针[^3] 。下面是一个跨平台兼容的例子: ```cpp #ifdef _WIN32 #include <tchar.h> #else #define _T(x) x #endif std::string getExeFilePathCrossPlatform(){ #ifdef _WIN32 return std::_tcsdup(_pgmptr); #else char result[ PATH_MAX ]; ssize_t count = ::readlink( "/proc/self/exe", result, PATH_MAX ); return std::string(result, (count > 0) ? count : 0 ); #endif } ``` 这个宏定义允许我们编写一次代码就能适应不同操作系统的特性差异。 --- ### 总结 每种方法都有各自的适用场景与局限性,在开发过程中应当依据项目需求选取恰当的技术手段完成任务。例如,当追求最高精度时推荐采用读取 `/proc/self/exe`;而对于某些特定环境下或许借助于 `argv[0]` 就已经足够满足基本功能诉求了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值