当前位置:  开发笔记 > 编程语言 > 正文

如何获取程序运行的目录?

如何解决《如何获取程序运行的目录?》经验,为你挑选了11个好方法。

是否存在与平台无关且与文件系统无关的方法来获取使用C/C++运行程序的目录的完整路径?不要与当前的工作目录混淆.(请不要建议使用库,除非它们是clib或STL等标准库.)

(如果没有平台/文件系统无关的方法,也欢迎在Windows和Linux中使用特定文件系统的建议.)



1> 小智..:

这是获取执行应用程序的完整路径的代码:

视窗:

int bytes = GetModuleFileName(NULL, pBuf, len);
if(bytes == 0)
    return -1;
else
    return bytes;

Linux的:

char szTmp[32];
sprintf(szTmp, "/proc/%d/exe", getpid());
int bytes = MIN(readlink(szTmp, pBuf, len), len - 1);
if(bytes >= 0)
    pBuf[bytes] = '\0';
return bytes;


当我看到看到`/ proc`的代码时,我的一部分就死了.所有的世界都不是Linux,即使在那个平台上,`/ proc`也应该被认为可以在版本之间变化,从拱形到拱形等等.
如何添加`char pBuf [256]; size_t len = sizeof(pBuf);`让解决方案更清晰.
Boo for/proc/pid/exe - 由于某种原因,OS X不支持.
如果他们在Linux上使用别名命令启动是argv [0]"命令名称"还是扩展?
我认为这是回答问题的唯一答案,对Windows和Linux都是如此.不错的工作.
顺便说一下,在Unix上获取二进制路径的一种更便携的方法是查看`argv [0]`,尽管这可以由启动你的进程伪造.

2> computinglif..:

如果在程序首次启动时获取当前目录,则可以有效地获取程序启动目录.将值存储在变量中,稍后在程序中引用它.这与保存当前可执行程序文件的目录不同.它不一定是同一个目录; 如果有人从命令提示符运行程序,则程序正在命令提示符的当前工作目录运行,即使程序文件位于其他位置.

getcwd是一个POSIX功能,所有POSIX兼容平台都支持开箱即用.你不需要做任何特别的事情(除了在Unix上使用unistd.h和在windows上使用direct.h).

由于您正在创建一个C程序,它将链接到默认的c运行时库,该库由系统中的所有进程链接(避免特制的异常),默认情况下它将包含此函数.CRT从不被视为外部库,因为它为操作系统提供了基本的标准兼容接口.

在Windows上,getcwd函数已被弃用,转而使用_getcwd.我想你可以用这种方式使用它.

#include   /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include 
    #define GetCurrentDir _getcwd
#else
    #include 
    #define GetCurrentDir getcwd
 #endif

 char cCurrentPath[FILENAME_MAX];

 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
     {
     return errno;
     }

cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */

printf ("The current working directory is %s", cCurrentPath);


很好的答案,但我认为"当前的工作目录"不是想要的.
在Windows上的IMO应该通常避免使用POSIXy命名的函数(其中一些以下划线开头).它们不是真正的Windows API,而是CRT.您要使用的Windows API是GetCurrentDirectory().http://msdn.microsoft.com/en-us/library/aa364934(VS.85).aspx
迈克的回答是正确的."当前目录"并不总是与运行二进制文件的目录相同.例如,如果应用程序在Windows上作为服务运行,则当前目录可能是C:\ Windows\System32,而二进制目录则不同.
你应该补充一点,即使某些文档说cCurrentpath可以为null并且将由getcwd分配getcwd似乎在Mac OS上没有分配东西并且悄悄地崩溃了你的程序
有一个小错误,但不幸的是我还无法编辑..第10行:cCurrentpath:应该是cCurrentPath

3> Octopus..:

这是来自cplusplus论坛

在Windows上:

#include 
#include 

std::string getexepath()
{
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}

在Linux上:

#include 
#include 
#include 

std::string getexepath()
{
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );
}

在HP-UX上:

#include 
#include 
#define _PSTAT64
#include 
#include 
#include 

std::string getexepath()
{
  char result[ PATH_MAX ];
  struct pst_status ps;

  if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
    return std::string();

  if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
    return std::string();

  return std::string( result );
}


对于Windows解决方案,我得到错误`错误:在使用MinGW进行编译时,无法将'char*'转换为'LPWCH {aka wchar_t*}'以将参数'2'转换为'DWORD GetModuleFileNameW(HMODULE,LPWCH,DWORD)'.
@Adrian,我一般不是一个Windows程序员,但是没有DEFINE或者告诉你的编译器自动使用_W()函数的味道吗?

4> Thorsten79..:

如果你想要一个没有库的标准方法:不.目录的整个概念不包含在标准中.

如果您同意对近标准库的某些(可移植)依赖是可以的:使用Boost的文件系统库并请求initial_path().

恕我直言,尽可能接近,有良好的业力(Boost是一套完善的高质量图书馆)


从Boost docs:template const Path&initial_path(); 返回:进入main()时的current_path().而current_path()就像'通过POSIX getcwd()'.这不是提问者所要求的.

5> Marqin..:

Filesystem TS 现在是一个标准(并受gcc 5.3+和clang 3.9+支持),所以你可以使用current_path()它的功能:

std::string path = std::experimental::filesystem::current_path();

在gcc(5.3+)中包含Filesystem,你需要使用:

#include 

并将您的代码与-lstdc++fs旗帜相关联.

如果要将文件系统与Microsoft Visual Studio一起使用,请阅读此内容.


从引用链接,`1-2)返回当前工作目录的绝对路径,就像POSIX getcwd一样.(2)如果发生错误则返回path().由于OP专门询问可执行文件的当前路径而不是当前工作目录,因此请注意.

6> Sam Redway..:

我知道现在很晚才回答这个问题,但我发现没有一个答案对我来说和我自己的解决方案一样有用.从CWD到bin文件夹获取路径的一种非常简单的方法是这样的:

int main(int argc, char* argv[])
{
    std::string argv_str(argv[0]);
    std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}

您现在可以将其用作相对路径的基础.所以例如我有这个目录结构:

main
  ----> test
  ----> src
  ----> bin

我想编译我的源代码到bin并写一个日志来测试我可以把这行添加到我的代码中.

std::string pathToWrite = base + "/../test/test.log";

我已经在Linux上使用完整路径,别名等尝试了这种方法,它工作得很好.

注意:

如果你在Windows上,你应该使用'\'作为文件分隔符而不是'/'.你也必须逃避这个例子:

std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));

我认为这应该有效但尚未经过测试,因此如果有效,则表示赞赏,如果没有,则表示感谢.


argv [0]是一个很好的主意,但不幸的是,我在Linux上得到的是“ ./my_executable_name”或“ ./make/my_executable_name”。基本上我得到的完全取决于我如何启动它

7> Michael Burr..:

不,没有标准的方法.我相信C/C++标准甚至不考虑目录(或其他文件系统组织)的存在.

在Windows上,当hModule参数设置为NULL时,GetModuleFileName()将返回当前进程的可执行文件的完整路径.我无法帮助Linux.

此外,您应该澄清是否需要当前目录或程序映像/可执行文件所在的目录.就目前而言,你的问题在这一点上有点含糊不清.



8> Jeremy Ruten..:

也许用argv [0]连接当前的工作目录?我不确定它是否适用于Windows,但它适用于Linux.

例如:

#include 
#include 
#include 

int main(int argc, char **argv) {
    char the_path[256];

    getcwd(the_path, 255);
    strcat(the_path, "/");
    strcat(the_path, argv[0]);

    printf("%s\n", the_path);

    return 0;
}

运行时,输出:

jeremy @ jeremy-desktop:〜/ Desktop $ ./test
/home/jeremy/Desktop/./test



9> Torbjörn Gyl..:

对于Win32,GetCurrentDirectory应该可以解决问题.



10> Adam Yaxley..:

在Windows上,最简单的方法是使用_get_pgmptr函数stdlib.h来获取指向字符串的指针,该字符串表示可执行文件的绝对路径,包括可执行文件名称.

char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe



11> eugensk..:

您不能将argv [0]用于此目的,通常它确实包含可执行文件的完整路径,但不是必须的 - 可以在字段中使用任意值创建进程.

还要注意,当前目录和带有可执行文件的目录是两个不同的东西,所以getcwd()也无法帮助你.

在Windows上使用GetModuleFileName(),在Linux上读取/ dev/proc/procID/..文件.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有