1

我需要帮助创建继承新的临时路径环境变量的子进程,然后使用子进程,它将在路径中指定的新文件夹中运行该进程。

例如,我将 C:\Test 添加到 Path 环境变量中,然后我不想通过使用 cmd.exe 作为子进程来运行程序

我在使用下面的行创建进程时遇到问题,它会弹出消息无法运行子进程

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");

如果我将 NULL 作为环境块传递,我将能够执行我的子进程,但它不会继承新的 Path 环境变量,因此 cmd.exe 无法运行当前路径环境中未指定的程序

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

这是我的代码:

// 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;
}

真的需要有人用答案来启发我

4

1 回答 1

1
// 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;
    }
}
于 2013-09-22T10:45:59.007 回答