23

I want to get the full path of the current process.

I use _getcwd to get the current working directory. But it not includes file name.

How can I get file name like: filename.exe?

Ronny Brendel
  • 4,777
  • 5
  • 35
  • 55
Phat Tran
  • 307
  • 1
  • 3
  • 14

8 Answers8

33

argv[0] of your main function is your filename.

A simple code snippet:

#include<stdio.h>
int main(int argc, char** argv)
{
    //access argv[0] here
}

If you cannot access/change code in main(), you can do something like this:

std::string executable_name()
{
#if defined(PLATFORM_POSIX) || defined(__linux__) //check defines for your setup

    std::string sp;
    std::ifstream("/proc/self/comm") >> sp;
    return sp;

#elif defined(_WIN32)

    char buf[MAX_PATH];
    GetModuleFileNameA(nullptr, buf, MAX_PATH);
    return buf;

#else

    static_assert(false, "unrecognized platform");

#endif
}
Cliveptr
  • 3
  • 1
  • 1
Seçkin Savaşçı
  • 3,446
  • 2
  • 23
  • 39
17

On windows you can use:

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

szExeFileName will contain full path + executable name

[edit]

For more portable solution use argv[0] or some other platform specific code. You can find such aproach here: https://github.com/mirror/boost/blob/master/libs/log/src/process_name.cpp.

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • 1
    This is not portable – sancelot Sep 22 '15 at 06:38
  • 1
    @sancelot there is no portable code for doing this, OP in one of his/her comments asked for win32 platform and so this answer. Also under windows you dont have access to argv[0] in all application types. btw. I have added some hints for making this in portable way. – marcinj Sep 22 '15 at 14:26
9

On Linux, the filename of your binary is the destination of a symlink at /proc/self/exe. You can use the readlink system call to find the destination of a symlink.

Note that this tells you the actual location on disk where the binary is stored, not simply the command the user used to start your program.

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
  • 1
    @SeçkinSavaşçı, I would imagine [GetModuleFileName](http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx) would do the trick. – chris Sep 03 '12 at 23:45
6

Here's a cross-platform way using boost (https://www.boost.org/)

#include <iostream>
#include <boost/dll.hpp>

int main( int argc, char **argv ) {

    std::cout << "hello world, this is [" << boost::dll::program_location().filename().string() << "]" << std::endl;

    std::cout << "or [" << boost::dll::program_location().string() << "] if you're not into the whole brevity thing." << std::endl;

    return 0;
}

compiled via

g++ -o hello_world hello_world.cpp -lboost_filesystem -lboost_system -ldl

results in the output

hello world, this is [hello_world]
or [/home/gjvc/tmp/hello_world] if you're not into the whole brevity thing.
gjvc
  • 81
  • 2
  • 3
4

As others have mentioned, the name of your executable is contained in argv[0]. If you need that, you could:

cout << argv[0] << endl;

If you need the name of a source file of the executable, C++ has a predefined macro you can use:

cout << __FILE__ << endl;

Go to here and scroll to "Predefined macro names"

3

You can use program_invocation_name from errno.h

https://linux.die.net/man/3/program_invocation_short_name

vromanov
  • 881
  • 6
  • 11
2

In Linux (POSIX?) there is an enviroment variable called _ that contains the current process.

$ echo $_
echo

In C++

#include <stdlib.h>     /* getenv */
#include<iostream>
int main(){
    std::cout << getenv("_") << '\n';
    return 0;
}

compile

$ c++ a.cpp -o a.out
$ ./a.out

prints ./a.out (or whatever is the executed line, including path).

This has certain advantages over the other approaches, it can be read globally (not passing argv[0]) and doesn't need file handling.

alfC
  • 14,261
  • 4
  • 67
  • 118
  • This doesn't work for me on my linux box. It prints the pid of and path to the shell. not the name of the current process. However, if I then call another prorgram via system, that child process will have the correct name. This seems to work slightly differently for different variants of unix as well. – Tom Tanner Jun 01 '16 at 07:58
  • @TomTanner, it may depend on the shell also. For example I get that the variable can contain the relative path of the executing line. For example `tmp/a.out` if I run it from a different directory. – alfC Jun 01 '16 at 15:38
1

You can usually get the executable file name from argv[0]:

#include <stdio.h>
int main(int argc, char* argv[])
{
 printf("Running: %s\n", argv[0]);
 return 0;
}

Indeed, there are ways for an application to execl() another application (or another similar function) and override this argument. It still is unconventional for the system to change it for that sort of application.

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 1
    wrong order of argc and argv, and I already gave the answer :) – Seçkin Savaşçı Sep 03 '12 at 23:20
  • 1
    Re *You can always get the executable file name from argv[0]* : Not always. It's convention to invoke `execl` with `argv[0]` set to the program name. It is also a hackable convention. Making argv[0] null is somewhat standard in secure environments. – David Hammen Sep 04 '12 at 00:41
  • Thanks to both. I fixed a few things in my answer, though there isn't much to worry about now. – E_net4 Sep 04 '12 at 10:25