19

So I run my app. I need for it to know where its executable is. How to find path to it using Boost.Filesystem?

Rella
  • 65,003
  • 109
  • 363
  • 636

6 Answers6

37
boost::filesystem::system_complete(argv[0]);

e.g.

[davka@bagvapp Debug]$ ./boostfstest 
/home/davka/workspaces/v1.1-POC/boostfstest/Debug/boostfstest

Note that this gives you the full path including the executable file name.

davka
  • 13,974
  • 11
  • 61
  • 86
  • +1 Is it possible to remove executable filename and keep only path to folder? – Rella Apr 17 '11 at 15:27
  • 1
    http://stackoverflow.com/questions/273691/using-progname-instead-of-argv0/273701#273701 – rubenvb Apr 17 '11 at 15:28
  • 1
    @Blender: check out the `parent_path()` method of the `path` class. My boost version is old so I don't have it to try – davka Apr 17 '11 at 15:31
  • Restoring parity, I can't see what's wrong with this either...@Blender, save it to a `std::string`, do a reverse find for `\\` and a substring to that point - voila. – Nim Apr 17 '11 at 19:39
  • 2
    @Nim : That's a bit obtuse -- `path` already has a [`parent_path()`](http://www.boost.org/doc/libs/release/libs/filesystem/v3/doc/reference.html#path-parent_path) member function. – ildjarn Apr 18 '11 at 00:42
  • @ildjarn, ofcourse there is the easy way! :) I completely missed the comment by @davka above mine!!! – Nim Apr 18 '11 at 07:31
  • 4
    This can fail in several ways since it relies on the search path. – ergosys Sep 10 '11 at 19:10
  • 4
    It won't work if you have `chdir`ed to another directory, and your app was run via a relative path, like `./myapp`. – Ruslan Mar 31 '17 at 11:43
  • 1
    You should call `path::canonical` on the resulting path if you wish to get at the original executable location. Otherwise if a symbolic link is used you'll get a path to where that is located. – edA-qa mort-ora-y Aug 06 '17 at 14:16
  • This just seems to use the current directory and does not search in the `PATH` environmental variable. So this will only work for local executables, not system ones. – coderforlife Aug 18 '23 at 21:14
34

You cannot, Boost.Filesystem does not provide such functionality.

But starting with Boost 1.61 you can use Boost.Dll and function boost::dll::program_location:

#include <boost/dll.hpp>
boost::dll::program_location().parent_path();
  • This works as expected. The boost::filesystem::current_path() will return the path of the executable. No matter which directory you run it from. – munsingh Jun 30 '20 at 08:45
  • @munsingh `current_path` returns "current directory", not executable path. If you run a program from the shell from a home folder, that folder will be your current directory, but you executable can be in `/usr/bin/something`. This is the most common way to execute command-line utilities on Unix systems. –  Jun 30 '20 at 08:46
  • This also will work: ```boost::dll::program_location().parent_path().parent_path();``` – Muzuri Aug 19 '21 at 14:31
10

You can't do it reliably with boost::filesystem.

However if you're on windows you can call GetModuleFileName to get the complete path of the executable and then use boost::filesystem to get the directory. ( see parent_path)

f4.
  • 3,814
  • 1
  • 23
  • 30
2

As discussed more comprehensively here, the most reliable way to do that is not through boost::filesystem. Instead, your implementation should take into the consideration the operating system on which the application is running.

However, for a quick implementation without portability concerns, you can check if your argv[0] returns the complete path to executable. If positive, you can do something like:

namespace fs=boost::filesystem;

fs::path selfpath=argv[0];

selfpath=selfpath.remove_filename();
Community
  • 1
  • 1
pdpcosta
  • 199
  • 1
  • 6
-2

From C++ 14 you don't need Boost, you can use the filesystem of the standard library you can do that easily: (I can confirm this works on Windows and Linux as well)

#include <iostream>
#include <filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
    fs::path p = argv[0]; // or "C:executable_name.exe";
    std::cout << "Current path is " << fs::current_path() << '\n'
              << "Absolute path for " << p << " is " << fs::absolute(p) << '\n'
          << "System complete path for " << p << " is " << fs::system_complete(p) << '\n';
}

Sample copied from the documentation: https://en.cppreference.com/w/cpp/experimental/fs/absolute

flatronka
  • 1,061
  • 25
  • 51
  • 5
    The problem is that: 1) this needs access to `argv` array 2) `argv[0]` might be missing (`argc` _can_ be 0) 3) yields invalid result if program found through environment variables 4) the example is incomplete - does not defined `argc`/`argv` and 5) `std::experimental` which is not really the standard library as the answer claims. –  Apr 05 '19 at 19:22
-34

If you mean from inside the executable that you're running, you can use boost::filesystem::current_path()

Ralf
  • 9,405
  • 2
  • 28
  • 46
  • 26
    This will not work if the program directory is different from the current working directory. For example, consider a program started from the shell in this manner: `./foo/program`. – Emile Cormier Apr 17 '11 at 15:05
  • 7
    great example of how bad answers become accepted on the site – Andry Aug 14 '18 at 15:44