【问题标题】:find name of the execute file from withing the program从程序中查找执行文件的名称
【发布时间】:2015-02-08 13:51:12
【问题描述】:

我正在寻找一种方法来查找运行它的可执行文件的名称。这意味着如果我有一个名为program 的文件运行我想得到它的名字的东西。

使用__FILE__ 不适合我,因为我需要可执行文件名而不是包含代码的 C 文件名。

我想知道是否有可以帮助我的 gcc 宏或我找不到的内置函数。

编辑: 同样使用argv[0] 也不合适,因为我不仅需要在main 内部调用该函数。

并且将 argv[0] 参数传递给可能需要此参数的所有函数也是不可接受的,因为它将在整个系统中使用(我需要通过它进行散列)。

【问题讨论】:

  • @zenith thnx。我只是将它添加为评论,指出它不符合我的需求。
  • 您需要它才能在 Windows 上工作,还是 POSIX 系统就足够了?
  • 我在linux上运行它
  • 但是您不能将argv[0] 传递给需要它的代码的任何部分吗?或者只是将argv[0] 设置为全局变量或其他东西,如果它太多传递?
  • 宏是在编译时扩展的,所以如果有人在编译后去更改可执行文件的名称,宏是没有问题的。

标签: c


【解决方案1】:
int main(int argc,char* argv[])
{
    printf("%s",argv[0]);
    return 0;
}

第一个参数(argv[0]) 包含正在运行的程序的名称。

【讨论】:

  • 您好,谢谢,很抱歉,使用 argv[0] 不符合我的需要,我只是在您回答时添加了编辑。
  • @Anton.P 复制argv[0] 的内容并随意使用?
  • @Anton.P 请用argv[0]将其标记为编辑,否则来这里的人认为Cool Guy完全误解了这个问题
  • @iharob 这是一种可能性,但我不想将名称作为参数传递给可能使用此功能的每个函数。不幸的是,功能太多了。
  • @Anton.P 然后使用全局变量,但我会传递变量。
【解决方案2】:

main() 在 C 中的标准定义是:

int main(int argc, char **argv)

argv[0] 包含执行的程序的名称。

【讨论】:

  • 您好,谢谢,很抱歉,使用 argv[0] 不符合我的需要,我只是在您回答时添加了编辑。
  • OP 曾提到反对argv[0]
  • 这是一个非常奇怪的要求。这个代码是高尔夫吗?
  • Anton,您可以定义全局指针,如char * exeName;,并在主函数中分配它,如exeName = argv [0];。因此,这个全局字符串将可用于您代码中的任何函数。
【解决方案3】:

main,将argv[0] 传递到您可能需要程序名称的任何地方。

或者,如果很多函数都需要它并且您想避免过多地传递它,请将它分配给全局变量。

您要求使用宏作为解决方案,但它们在编译时被扩展。并且由于编译后可执行文件的名称可以更改,所以在编译时无法确定你想要什么,所以宏是没有问题的。

【讨论】:

  • 程序很大,包含了几十个这样的模块,我添加的功能是一个小功能,我不想为了添加一个小功能而对所有模块进行更改。
  • @Anton.P 我能看到的唯一解决方案是添加两行来定义一个全局变量,并在main 中分配argv[0] 给它。两条小线会不会修改太多?
  • 在我看来,您不必对所有模块进行更改。
【解决方案4】:

经常从main 中记住argv[0] 就足够了。

如果不是这种情况——例如,如果你是一个共享库,或者你担心你的调用者用伪造的argv[0] 开始你(这可能但不寻常),你可以在 POSIX-安装了/proc 的兼容系统,使用readlink 解析/proc/self/exe 并获取运行进程的主二进制文件的路径:

#include <limits.h>
#include <unistd.h>

// Note that readlink does not null-terminate the result itself. This
// is important if the link target contains null bytes itself, I suppose,
// but it means that you have to take care that the null-terminator is
// placed yourself if you're going to use the file name as a string.
char buf[PATH_MAX] = { 0 };
readlink("/proc/self/exe", buf, PATH_MAX);

在 Windows 上,有 GetModuleFileName 函数:

#include <windows.h>

TCHAR buf[MAX_PATH];
GetModuleFileName(NULL, buf, MAX_PATH);

【讨论】:

    【解决方案5】:

    启动名称是通过main()argv[0] 给出的,可以认为是常量。

    那么为什么不使用对它的全局引用使其在整个程序中可用。

    progname.h

    #ifndef PROGNAME_H
    #define PROGNAME_H
    
    extern char * progname;
    
    #endif
    

    main.c

    #include "progname.h"
    
    char * progname = NULL;
    
    int main(int argc, char ** argv)
    {
      progname = argv[0];
    
      ...
    
    }
    

    像这样从任何地方访问它

    模块1.c

    #include <stdio.h>
    #include "progname.h"
    
    void f(void)
    {
      printf("progname='%s'\n", progname ?progname :"<not set>");
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-27
      • 2015-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多