Link to home
Start Free TrialLog in
Avatar of davidhq
davidhq

asked on

How to get the path to executable from Visual C++ Console App (CRT, not MFC)

Hi!

I want get the path to the executable. In mfc this is done with GetProcessImageFileName or GetModuleFileNameEx, but this is not possible using a 'standard' c++..

Argv[0] only returns the file name. So how do I get this info?

Thank you!
Avatar of grg99
grg99

AFAIK there is no "standard" way in C or C++ to inquire about this.

You could do a combination of argv[0], and if that does not look like a full path,  and get the current working directory, putting those two together might be the right thing to do.  Or maybe not.  You'll have to experiment with various combinations of relative paths and various cwd's.



Avatar of davidhq

ASKER

Thank you for the comment. The problem is that the exe is in PATH and when run from a different location, the working directory will be wrong. So I need the path to the exe, not the current directory.. Any further ideas? thank you!
david
Avatar of pepr
The GetModuleFileName() and GetModuleFileNameEx() are win32 system functions. No need to use MFC to use them. See http://msdn2.microsoft.com/en-us/library/ms683197.aspx and http://msdn2.microsoft.com/en-us/library/ms683198.aspx. The GetModuleFileName() (i.e. without Ex) is implemented in  Kernel32 and you get it when including windows.h. The Ex version is implemented inside psapi library and you have to include psapi.h.

You cannot hope for "more standard" way of getting the full executable path. To give you at least one reason why... For example, the path can be returned in Unicode if NTFS is used. This may not be usual in other file systems these days.
ASKER CERTIFIED SOLUTION
Avatar of pepr
pepr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Another option is to get the value of the PATH variable (getenv()), break it into pieces (strtok()), build a full path using the directory from the path and the exe from argv[0], and test for its existence (_stat()).

When you find the one that exists, you will now have the full path.
Avatar of davidhq

ASKER

Thank you all.. I think the solution GetModuleFileName is the best.. However I have a strange problem with it..

Error      6      error C2065: 'DWORD' : undeclared identifier      
Error      10      error C3861: 'GetModuleFileName': identifier not found      

I did #include <windows.h>

hmm? thank you!
david
beside of strtok the idea of wayside is good.

beside of typo's the below should do the job.

Regards, Alex



#include <sys/stat.h>
#include <stdlib.h>
#include <string>
using namespace std;

string getexepath(const string& file)
{
     struct stat fs;
     // first check  the file only
     if (stat(file.c_str(), &fs) == 0)
           return file;
     // get working directory
     string cwd(512, '\0');
     if (getcwd(&cwd[0], cwd.length()) == NULL)
           return ""; // error retrieving current working directory
     cwd.resize(strlen(cwd.c_str());  // make correct length
     // check whether backslash or slash was used
     int pos = (int)cwd.find_first_of("\\/");
     char cslash = '/';  // take forward slash as default
     if (pos != string::npos && cwd[pos] == '\\')
         cslash = '\\';
     string path = cwd + cslash + file;
     if (stat(path.c_str(), &fs) == 0)
           return path;
     
     string pathenv = getenv("PATH");
     pathenv += ';';  // add semicolon for parsing
     int lpos = 0;
     int npos = 0;
     while ((npos = (int)pathenv.find(';', lpos)) != string::npos)
     {
            if (lpos < npos)
            {
                  path = pathenv.substr(lpos, npos - lpos) + cslash + file;
                  if (stat(path.c_str(), &fs) == 0)
                       return path;
            }
            lpos = npos+1;
     }
      return "";
}

>>>> I did #include <windows.h>
DWORD is defined in windef.h which was included by windows.h.

I assume you included it above stdafx.h where it was ignored. Or you forgot to switch off Precompiled Header.
>>>> I think the solution GetModuleFileName is the best..
That will only work on windows platform. And you have to include all windows api via windows.h.

But beside of that you are right.
Avatar of davidhq

ASKER

itsmeandnobodyelse: thank you as well.. yes -> I only need it on windows. Sorry I accepted the other solution (I'm also quite new on EE, so maybe I should have accepted both solutions - didn't realize it)

Regarding the inclusion of "windows.h" - yes I forgot about that gotcha (long time since I last wrote unmanaged code:)

I also had to un-set unicode to get rid of the error when compiling char buffer[]. Here is how to do it:

Project properties / General / Character Set: Use Unicode
changed to "Not set"

Thank you again.. Using EE has paid off big time already.

Bye!
david
>>>> so maybe I should have accepted both solutions

It is not important. You may do so next time.

Thank you for your comment.

Regards, Alex