سؤال

I need help with creating child process inheriting the new temporary Path environment variable then using the child process, it will run the process inside new folder specified in the Path.

Example, I add C:\Test into Path environment variable,and then i wan't to run a program by using cmd.exe as the child process

I'm having problem to create process by using the line below,it will pop up message unable to run the child process

Utilities::createProcess(_T("C:\\Windows\\system32\\cmd.exe"),_T(""),txtbuff);
// txtbuff is a WCHAR with size of 4096
// it contains the concatenation of _T("Path=C:\\Test;\0"); and pszOldPath
// pszOldPath get its value from GetEnvironmentVariable(_T("PATH"), pszOldPath,4096);
// The concantenated string will have the form of _T("Path=path1\0path2\0....\0\0");

If i pass NULL as my environment block,I'll be able to execute my child process but it won't inherit the new Path environment variable thus cmd.exe cannot run a program that is not specified in current path environment

Utilities::createProcess(_T("C:\\Windows\\system32\\cmd.exe"),_T(""),NULL);

This is my code:

// Utilities.h
namespace Utilities
{
    bool createProcess(LPCWSTR filename,LPWSTR arg,LPTSTR envpath)
    {
        DWORD dwRet;
        LPTSTR pszOldVal;
        TCHAR pszDest[BUFSIZE] = _T("");
        pszOldVal = (LPTSTR) malloc(BUFSIZE*sizeof(TCHAR));
        if(envpath != NULL)
        {
            dwRet = GetEnvironmentVariable(_T("PATH"), pszOldVal, BUFSIZE);
            if(!dwRet)
            {
                MessageBox(NULL,_T("Get environment variables failed."),_T("Error"),MB_OK);
                return false;
            }
            else
            {
                StringCchCat(pszDest,BUFSIZE,_T("Path="));
                StringCchCat(pszDest,BUFSIZE,envpath);
                StringCchCat(pszDest,BUFSIZE,_T(";\0"));
                StringCchCat(pszDest,BUFSIZE,pszOldVal);
                //MessageBox(NULL,pszDest,_T("Environtment Variables"),MB_OK);
            }
        }
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb= sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        if(!CreateProcess(filename,arg,NULL,NULL,NULL,NULL,pszDest,NULL,&si,&pi))
        {
            MessageBox(NULL,_T("Unable to create process."),_T("Error"),MB_OK);
            return false;
        }
        //WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        free(pszOldVal);
        return true;
    }
}
// Main.cpp
// At Wnd Proc
LRESULT CALLBACK(......)
{
case WM_COMMAND:
    switch(wParam)
    {
        case ID_TEST:
            Utilities::getDlgText(hWnd,ID_INPUT_CPP,txtbuff);
            if(_tcscmp(txtbuff, _T("")) == 0)
            {
                MessageBox(NULL,_T("Please make sure you select folder."),_T("Error"),MB_OK);
                break;
            }
            // Environtment variable"MyVar=MyValue\0MyOtheVar=MyOtherValue\0\0"

// This is where Im having problem right now
            Utilities::createProcess(_T("C:\\Windows\\system32\\cmd.exe"),_T(""),txtbuff,NULL);
            break;
    }
    return true;
}

Really need someone to enlighten me with the answer

هل كانت مفيدة؟

المحلول

// Utilities.h
namespace Utilities
{
    bool createProcess(LPCWSTR filename, LPWSTR arg, LPWSTR envpath)
    {
        std::vector<WCHAR> oldPath;
        std::vector<WCHAR> newPath;
        DWORD dwOldLen = 0;

        if(envpath != NULL)
        {
            DWORD dwLen = GetEnvironmentVariable(L"PATH", NULL, 0);
            if (dwLen) {
                oldPath.resize(dwLen);
                dwOldLen = GetEnvironmentVariable(L"PATH", oldPath.data(), dwLen);
                if(dwOldLen + 1 != dwLen)
                {
                    MessageBox(NULL,_T("Get environment variables failed."),_T("Error"),MB_OK);
                    return false;
                }
            }
            size_t newLen = dwOldLen + wcslen(envpath) + 8; //8 for "path=" ";" and double null terminating
            newPath.resize(newLen);
            std::fill(newPath.begin(), newPath.end(), 0);
            memcpy(newPath.data(), L"Path=", 5 * 2);
            memcpy(newPath.data() + 5, oldPath.data(), dwOldLen * 2);
            memcpy(newPath.data() + 5 + dwOldLen, L";", 2);
            memcpy(newPath.data() + 6 + dwOldLen, envpath, wcslen(envpath) * 2);
        }
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb= sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        if(!CreateProcess(filename,arg,NULL,NULL,NULL,CREATE_UNICODE_ENVIRONMENT,newPath.data(),NULL,&si,&pi))
        {
            MessageBox(NULL,_T("Unable to create process."),_T("Error"),MB_OK);
            return false;
        }
        //WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return true;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top