c++ifstreamworking-directorycustom-protocol

C++ Application root when using custom protocol


I've create a C++ application on windows that is started through a custom protocol, using the following technique: http://msdn.microsoft.com/en-us/library/ie/aa767914(v=vs.85).aspx.

It loads a config file using ifstream, that's located in the same folder as the executable. So if I use a relative path (ifstream myfile ("config.cfg");) it works like a charm. But if i call my application using the custom protocol in IE like this: myprotocol:\\ it's not able to load the file while I execute the same executable.

Can someone explain to me why my program behaves differently when executed through a custom protocol and what i should to to make my application load the file without having to use a absolute path?

int main(int argc, char* argv[])
{
    wchar_t buffer[MAX_PATH];
    GetModuleFileName( NULL, buffer, MAX_PATH );
    std::wcout << buffer;

    std::string line;
    std::ifstream file ("config.cfg);
    if(file.is_open())
    {
        std::cout << "Succes";
    } 
    else
    {
        std::cout << "Could not load file";
        return -1;
    }
    return 0;
}

GetModuleFileName correctly gives the executable's path in both cases. It was just a little test.

Any help is appreciated, Alexander


Solution

  • You are incorrectly assuming that the application is called from the folder it is located.

    You will have to get the path of the current application and then combine it with the name of the config file. For example:

    char buffer[MAX_PATH];
    GetModuleFileNameA( NULL, buffer, MAX_PATH );
    PathRemoveFileSpecA(buffer);
    char cfg_path[MAX_PATH];
    PathCombineA(cfg_path, MAX_PATH, buffer, "config.cfg");
    // cfg_path now contains the full path to the config file
    

    An alternative solution is to pass the path to the config file as the first argument to the application. This will mean changing the command in the registry to something like "C:\Program Files\MyProtocol\MyProtocol.exe" "C:\Program Files\MyProtocol\config.cfg" "%1". Then the code can be changed to the following:

    int main(int argc, char* argv[]) {
        if( argc<2 ) return -1;
    
        std::ifstream file(argv[1]);
        // ...
    }