Get path of executable

前端 未结 23 1509
清歌不尽
清歌不尽 2020-11-22 07:04

I know this question has been asked before but I still haven\'t seen a satisfactory answer, or a definitive \"no, this cannot be done\", so I\'ll ask again!

All I wa

相关标签:
23条回答
  • 2020-11-22 07:42

    For Windows, you have the problem of how to strip the executable from the result of GetModuleFileName(). The Windows API call PathRemoveFileSpec() that Nate used for that purpose in his answer changed between Windows 8 and its predecessors. So how to remain compatible with both and safe? Luckily, there's C++17 (or Boost, if you're using an older compiler). I do this:

    #include <windows.h>
    #include <string>
    #include <filesystem>
    namespace fs = std::experimental::filesystem;
    
    // We could use fs::path as return type, but if you're not aware of
    // std::experimental::filesystem, you probably handle filenames
    // as strings anyway in the remainder of your code.  I'm on Japanese
    // Windows, so wide chars are a must.
    std::wstring getDirectoryWithCurrentExecutable()
    {
        int size = 256;
        std::vector<wchar_t> charBuffer;
        // Let's be safe, and find the right buffer size programmatically.
        do {
            size *= 2;
            charBuffer.resize(size);
            // Resize until filename fits.  GetModuleFileNameW returns the
            // number of characters written to the buffer, so if the
            // return value is smaller than the size of the buffer, it was
            // large enough.
        } while (GetModuleFileNameW(NULL, charBuffer.data(), size) == size);
        // Typically: c:/program files (x86)/something/foo/bar/exe/files/win64/baz.exe
        // (Note that windows supports forward and backward slashes as path
        // separators, so you have to be careful when searching through a path
        // manually.)
    
        // Let's extract the interesting part:
        fs::path path(charBuffer.data());  // Contains the full path including .exe
        return path.remove_filename()  // Extract the directory ...
                   .w_str();           // ... and convert to a string.
    }
    
    0 讨论(0)
  • 2020-11-22 07:43

    For windows:

    GetModuleFileName - returns the exe path + exe filename

    To remove filename
    PathRemoveFileSpec

    0 讨论(0)
  • 2020-11-22 07:44

    in Unix(including Linux) try 'which', in Windows try 'where'.

    #include <stdio.h>
    
    #define _UNIX
    
    int main(int argc, char** argv)
    {
            char cmd[128];
            char buf[128];
            FILE* fp = NULL;
    #if defined(_UNIX)
            sprintf(cmd, "which %s > my.path", argv[0]);
    #else
            sprintf(cmd, "where %s > my.path", argv[0]);
    #endif
            system(cmd);
            fp = fopen("my.path", "r");
            fgets(buf, sizeof(buf), fp);
            fclose(fp);
    
            printf("full path: %s\n", buf);
            unlink("my.path");
    
            return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 07:49

    I'm not sure about Linux, but try this for Windows:

    #include <windows.h>
    #include <iostream>
    
    using namespace std ;
    
    int main()
    {
         char ownPth[MAX_PATH]; 
    
         // When NULL is passed to GetModuleHandle, the handle of the exe itself is returned
         HMODULE hModule = GetModuleHandle(NULL);
         if (hModule != NULL)
         {
             // Use GetModuleFileName() with module handle to get the path
             GetModuleFileName(hModule, ownPth, (sizeof(ownPth))); 
             cout << ownPth << endl ;
             system("PAUSE");
             return 0;
         }
         else
         {
             cout << "Module handle is NULL" << endl ;
             system("PAUSE");
             return 0;
         }
    }
    
    0 讨论(0)
  • 2020-11-22 07:49

    The following works as a quick and dirty solution, but note that it is far from being foolproof:

    #include <iostream>
    
    using namespace std ;
    
    int main( int argc, char** argv)
    {
        cout << argv[0] << endl ;
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 07:51

    Using args[0] and looking for '/' (or '\\'):

    #include <string>
    #include <iostream> // to show the result
    
    int main( int numArgs, char *args[])
    {
        // Get the last position of '/'
        std::string aux(args[0]);
    
        // get '/' or '\\' depending on unix/mac or windows.
    #if defined(_WIN32) || defined(WIN32)
        int pos = aux.rfind('\\');
    #else
        int pos = aux.rfind('/');
    #endif
    
        // Get the path and the name
        std::string path = aux.substr(0,pos+1);
        std::string name = aux.substr(pos+1);
        // show results
        std::cout << "Path: " << path << std::endl;
        std::cout << "Name: " << name << std::endl;
    }
    

    EDITED: If '/' does not exist, pos==-1 so the result is correct.

    0 讨论(0)
提交回复
热议问题