首页 > 解决方案 > 寻找C++程序的执行路径

问题描述

在我正在工作的 C++ 命令行程序中,我需要找到执行路径,即调用 .exe 文件的路径。例如,如果文件被存储,D:\stored\location\但它是从其他目录调用的,比如D:\executed\here\,我应该得到D:\executed\here\路径。命令提示符应该看起来像这样:-

D:\executed\here> D:\stored\location\program_name.exe getpath
Path of execution is : D:\executed\here

我尝试按照此处此处的说明使用 GetModuleFileName ,但我得到了\stored\here

是否有一种跨平台的方式来查找“执行路径”?

注意:- 我正在使用 VSCode。

编辑:编译器的版本是:g++(i686-posix-dwarf-rev0,由 MinGW-W64 项目构建)8.1.0 旁注:- 出于某种原因,包含后#include<filesystem>std::filesystem显示错误:'std::filesystem' has not been声明”,所以我无法使用 filesystem.h

标签: c++path

解决方案


C++11 的答案

出于好奇,我将 MinGW g++ 安装到了我的 git-bash 中(遵循如何在 Git Bash (Windows) 中安装 gcc。这立即奏效,但第一个坏惊喜很快就来了:

ds32737@lapeks415-017 MINGW64 /d/ds32737/Entwicklung/tests/C++/execPath
$ which g++
/d/MinGW/bin/g++

ds32737@lapeks415-017 MINGW64 /d/ds32737/Entwicklung/tests/C++/execPath
$ g++ --version
g++.exe (MinGW.org GCC-6.3.0-1) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

哦,哎呀!克++ 6.3。这解释了 OPs 的问题std::filesystem(我也得到了他们的支持)。

因此,我修改了另一个答案,将其反向移植到 C++11。

我的 C++11 符合 MCVE:

// Declaration (Header):

// standard C++ header:
#include <string>

// returns file path of this executable
std::string getExecPath();

/**************************************************************************/

// Definition (C++ Source):

// standard C++ header:
#include <cstring>
#include <codecvt>
#include <locale>

// OS header:
#ifdef _WIN32 // Is this Windows?
#include <windows.h>
#else // (not) _WIN32 // Then it's hopefully Linux.
#include <unistd.h>
#endif // _WIN32

std::string getExecPath()
{
#ifdef _WIN32 // Is this Windows?
  std::wstring path(1024, L'\0');
  const DWORD len
    = GetModuleFileNameW(NULL, &path[0], (DWORD)path.size());
  if (!len) return std::string(); // ERROR!
  path.resize(len);
  std::wstring_convert<std::codecvt_utf8<wchar_t>> convU16ToU8;
  return convU16ToU8.to_bytes(path);
#else // (not) _WIN32 // Then it's hopefully Linux.
  std::string path(1024, '\0');
  ssize_t len
    = readlink("/proc/self/exe", &path[0], path.size());
  if (len < 0) return std::string(); // ERROR!
  path.resize(len);
  return path;
#endif // _WIN32
}

std::string getCWD()
{
#ifdef _WIN32 // Is this Windows?
  std::wstring path(1024, L'\0');
  const DWORD len
    = GetCurrentDirectoryW(path.size(), &path[0]);
  if (!len) return std::string(); // ERROR!
  path.resize(len);
  std::wstring_convert<std::codecvt_utf8<wchar_t>> convU16ToU8;
  return convU16ToU8.to_bytes(path);
#else // (not) _WIN32 // Then it's hopefully Linux.
  std::string path(1024, '\0');
  if (!getcwd(&path[0], path.size())) return std::string(); // ERROR!
  size_t len = std::strlen(path.c_str());
  path.resize(len);
  return path;
#endif // _WIN32
}

/**************************************************************************/

// Test:

// standard C++ header:
#include <iostream>

int main()
{
  std::cout
    << "Exec. Path:   " << getExecPath() << '\n'
    << "Current Dir.: " << getCWD() << '\n';
}

MinGW 中的测试会话(g++ 6.3):

ds32737@lapeks415-017 MINGW64 /d/ds32737/Entwicklung/tests/C++/execPath/C++11
$ g++ -std=c++11 -O2 testExecPath.cc && mkdir test ; cd test ; ../a.exe
Exec. Path:   D:\ds32737\Entwicklung\tests\C++\execPath\C++11\a.exe
Current Dir.: D:\ds32737\Entwicklung\tests\C++\execPath\C++11\test

ds32737@lapeks415-017 MINGW64 /d/ds32737/Entwicklung/tests/C++/execPath/C++11/test
$

大肠杆菌测试:

g++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && mkdir test ; cd test ; ../a.out
Exec. Path:   /tmp/1609678428-623235554/a.out
Current Dir.: /tmp/1609678428-623235554/test

笔记:

我没有意识到这一点,因为我以前从未在 MinGW 中使用过 g++:也在 MinGW
_WIN32中定义,并且使用了相应的代码(并且必须使用)。
(以前,我使用_MSC_VER它仅激活 MSVC 的 Windows 代码。在这种情况下,我得到了一个编译器错误,因为readlink()它不可用。即使它可能没有在 Linux 上完成它应该做的事情。)


推荐阅读