Search code examples
c++chartype-conversionconstantswchar-t

Use SHGetKnownFolderPath in path of CreateProcess to run program


I am trying to use the function SHGetKnownFolderPath() that gets the directory of the user's localappdata and convert the PWSTR (which is a wchar_t*) into a LPCSTR (which is a const char*) then add the program to the LPCSTR to so it can be used in CreateProcess.

I figured how to use SHGetKnownFolderPath and print the path to the console using printf(%ls%, path) and figured out how to use CreateProcess to execute an .exe file, but I don't know how to make PWSTR into a const char* and include the program I want to be executed into that const char*.

#include <Windows.h>
#include <fstream>
#include <shlobj_core.h>
#include <string>
#include <KnownFolders.h>
#include <wchar.h>

int main () {
    //SHGetKnownFolderPath function
    PWSTR path = NULL;
    HRESULT path_here = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path);

    //CreateProcess funtion
    STARTUPINFO info = { sizeof(info) };
    PROCESS_INFORMATION processInfo;
    const char* execute = //Want to have path_here plus another folder and an .exe program.
    BOOL create = CreateProcess(execute, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo);
.......................
    }

I wouldn't say I know a lot about coding and there is probably something important I don't know about yet. Any help would be appreciated.

EDIT

I think it would be more helpful if I showed this other part of my code. The following code is right after the code I've written above:

if (create){
    WaitForSingleObject(processInfo.hProcess, INFINITE);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
 }

Solution

  • Don't convert to char at all. SHGetKnownFolderPath() returns a Unicode string. Use CreateProcessW() explicitly so you can pass it a Unicode string:

    #include <Windows.h>
    #include <fstream>
    #include <shlobj_core.h>
    #include <string>
    #include <KnownFolders.h>
    #include <wchar.h>
    
    int main ()
    {
        PWSTR path = NULL;
        HRESULT hres = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path);
        if (SUCCEEDED(hres))
        {
            STARTUPINFOW info = { sizeof(STARTUPINFOW) };
            PROCESS_INFORMATION processInfo;
            std::wstring execute = std::wstring(path) + L"\\folder\\program.exe";
            CoTaskMemFree(path);
            BOOL create = CreateProcessW(&execute[0], NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo);
            // ...
        }
        return 0;
    }