简体   繁体   English

C ++ WinApi CreateProcess无法使用环境块创建子进程

[英]C++ WinApi CreateProcess Unable To Create Child Process With Environment Block

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. 我需要创建继承新的临时Path环境变量的子进程的帮助,然后使用该子进程,它将在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 例如,我将C:\\ Test添加到Path环境变量中,然后我不想通过使用cmd.exe作为子进程来运行程序

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 如果我将NULL作为环境块传递,则可以执行子进程,但它不会继承新的Path环境变量,因此cmd.exe无法运行当前路径环境中未指定的程序

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 c++ (WinAPI) 中的 CreateProcess 之后使用 ctrl+c 终止子进程 - Terminate a child process with ctrl+c after CreateProcess in c++ (WinAPI) c ++ winapi CreateProcess被认为是恶意的 - c++ winapi CreateProcess Suspended recognized as malicious 带有命令行的C ++ Winapi CreateProcess问题 - C++ Winapi CreateProcess issue with command line winApi 使用 C++ 创建进程 - winApi create process using c++ c++ 如何写入使用 createProcess 创建的进程 - c++ how to write to a process that was created with createProcess (C ++,Windows)没有控制台窗口的生成子进程(使用CreateProcess) - (C++, Windows) Spawn child process without console window (using CreateProcess) C ++ WINAPI:如何在强制终止调用(父)进程时终止子进程? - C++ WINAPI: How to kill child processes when the calling (parent) process is forcefully terminated? C ++进程管理:Linux中的WinAPI“SetProcessShutdownParameters”? - C++ process management: WinAPI “SetProcessShutdownParameters ” in Linux? C ++ WIN API:使用CreateProcess创建子进程时,是否需要使输入参数具有全局生命周期? - C++ WIN API: When creating a child process using CreateProcess, do I need to make the input parameters have a global lifetime? 将CreateProcess()的stdout重定向到管道并在另一个进程C ++ Windows中读取它 - Redirecting stdout of CreateProcess() to a pipe and reading it in another process c++ windows
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM