?
Solved

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

Posted on 2007-10-17
11
Medium Priority
?
15,091 Views
Last Modified: 2013-12-14
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!
0
Comment
Question by:davidhq
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 22

Expert Comment

by:grg99
ID: 20092481
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.



0
 

Author Comment

by:davidhq
ID: 20092547
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
0
 
LVL 29

Expert Comment

by:pepr
ID: 20092834
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.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 29

Accepted Solution

by:
pepr earned 400 total points
ID: 20092887
Try the code like this:

#include <windows.h>
...
    char buffer[MAX_PATH];
    DWORD dwResult = GetModuleFileName(NULL, buffer, MAX_PATH);
    //if (dwResult == 0)
    //    throw runtime_error("The GetModuleFileName() failed.\n");
    std::string fullExeName(buffer);
    std::cout << "My full executable name is '" << fullExeName << "'\n";

This was cut from the application that is not compiled as Unicode enabled. For Unicode path, you have to play with the buffer.
0
 
LVL 14

Expert Comment

by:wayside
ID: 20093327
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.
0
 

Author Comment

by:davidhq
ID: 20093647
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
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20093789
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 "";
}

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20093840
>>>> 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.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20093876
>>>> 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.
0
 

Author Comment

by:davidhq
ID: 20094124
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
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20094686
>>>> 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
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question