首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CreateProcess()和CreatePipe()从cmd.exe读取输出

如何使用CreateProcess()和CreatePipe()从cmd.exe读取输出
EN

Stack Overflow用户
提问于 2016-03-13 19:35:54
回答 5查看 14K关注 0票数 16

如何使用CreateProcess()和CreatePipe()从cmd.exe读取输出

我一直在尝试创建一个子进程来执行cmd.exe使用命令行指定/K dir..。其目的是使用管道将命令的输出读回到父进程中。

我已经有了CreateProcess()工作,但是涉及管道的步骤给我带来了麻烦。使用管道,新的控制台窗口不会显示(与以前一样),并且父进程停滞在调用ReadFile()..。

有人知道我做错了什么吗?

代码语言:javascript
复制
#include 
#include 
#include 

#define BUFFSZ 4096

HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;

int wmain(int argc, wchar_t* argv[]) 
{
    int result;
    wchar_t aCmd[BUFFSZ] = TEXT("/K dir"); // CMD /?
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;

    printf("Starting...\n");

    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

    // Create one-way pipe for child process STDOUT
    if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0)) {
        printf("CreatePipe() error: %ld\n", GetLastError());
    }

    // Ensure read handle to pipe for STDOUT is not inherited
    if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
        printf("SetHandleInformation() error: %ld\n", GetLastError());
    }

    // Create one-way pipe for child process STDIN
    if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &sa, 0)) {
        printf("CreatePipe() error: %ld\n", GetLastError());
    }

    // Ensure write handle to pipe for STDIN is not inherited
    if (!SetHandleInformation(g_hChildStd_IN_Rd, HANDLE_FLAG_INHERIT, 0)) {
        printf("SetHandleInformation() error: %ld\n", GetLastError());
    }

    si.cb = sizeof(STARTUPINFO);
    si.hStdError = g_hChildStd_OUT_Wr;
    si.hStdOutput = g_hChildStd_OUT_Wr;
    si.hStdInput = g_hChildStd_IN_Rd;
    si.dwFlags |= STARTF_USESTDHANDLES;

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    // Pipe handles are inherited
    sa.bInheritHandle = true;

    // Creates a child process
    result = CreateProcess(
        TEXT("C:\\Windows\\System32\\cmd.exe"),     // Module
        aCmd,                                       // Command-line
        NULL,                                       // Process security attributes
        NULL,                                       // Primary thread security attributes
        true,                                       // Handles are inherited
        CREATE_NEW_CONSOLE,                         // Creation flags
        NULL,                                       // Environment (use parent)
        NULL,                                       // Current directory (use parent)
        &si,                                        // STARTUPINFO pointer
        &pi                                         // PROCESS_INFORMATION pointer
        );

    if (result) {
        printf("Child process has been created...\n");
    }
    else {
        printf("Child process could not be created\n");
    }

    bool bStatus;
    CHAR aBuf[BUFFSZ + 1];
    DWORD dwRead;
    DWORD dwWrite;
    // GetStdHandle(STD_OUTPUT_HANDLE)

    while (true) {
        bStatus = ReadFile(g_hChildStd_OUT_Rd, aBuf, sizeof(aBuf), &dwRead, NULL);
        if (!bStatus || dwRead == 0) {
            break;
        }
        aBuf[dwRead] = '\0';
        printf("%s\n", aBuf);
    }

        // Wait until child process exits
        WaitForSingleObject(pi.hProcess, INFINITE);

        // Close process and thread handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);

        printf("Stopping...\n");

        return 0;
    }
EN

Stack Overflow用户

发布于 2019-02-14 19:31:12

我也有同样的情况。在我使用Lib的情况下,需要执行内部exe并读取输出。下面的代码可以正常工作,没有任何问题。

代码语言:javascript
复制
void executeCMDInNewProcessAndReadOutput(LPSTR lpCommandLine)
    {
        STARTUPINFO si;
        SECURITY_ATTRIBUTES sa;
        PROCESS_INFORMATION pi;
        HANDLE g_hChildStd_IN_Rd, g_hChildStd_OUT_Wr, g_hChildStd_OUT_Rd, g_hChildStd_IN_Wr;  //pipe handles
        char buf[1024];           //i/o buffer

        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.bInheritHandle = TRUE;
        sa.lpSecurityDescriptor = NULL;

        if (CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &sa, 0))   //create stdin pipe
        {
            if (CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0))  //create stdout pipe
            {

                //set startupinfo for the spawned process
                /*The dwFlags member tells CreateProcess how to make the process.
                STARTF_USESTDHANDLES: validates the hStd* members.
                STARTF_USESHOWWINDOW: validates the wShowWindow member*/
                GetStartupInfo(&si);

                si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
                si.wShowWindow = SW_HIDE;
                //set the new handles for the child process
                si.hStdOutput = g_hChildStd_OUT_Wr;
                si.hStdError = g_hChildStd_OUT_Wr;
                si.hStdInput = g_hChildStd_IN_Rd;

                //spawn the child process
                if (CreateProcess(NULL, lpCommandLine, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
                    NULL, NULL, &si, &pi))
                {
                    unsigned long bread;   //bytes read
                    unsigned long avail;   //bytes available
                    memset(buf, 0, sizeof(buf));

                    for (;;)
                    {
                        PeekNamedPipe(g_hChildStd_OUT_Rd, buf, 1023, &bread, &avail, NULL);
                        //check to see if there is any data to read from stdout
                        if (bread != 0)
                        {
                            if (ReadFile(g_hChildStd_OUT_Rd, buf, 1023, &bread, NULL))
                            {
                                break;
                            }
                        }
                    }

                    //clean up all handles
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);
                    CloseHandle(g_hChildStd_IN_Rd);
                    CloseHandle(g_hChildStd_OUT_Wr);
                    CloseHandle(g_hChildStd_OUT_Rd);
                    CloseHandle(g_hChildStd_IN_Wr);
                }
                else
                {
                    CloseHandle(g_hChildStd_IN_Rd);
                    CloseHandle(g_hChildStd_OUT_Wr);
                    CloseHandle(g_hChildStd_OUT_Rd);
                    CloseHandle(g_hChildStd_IN_Wr);
                }
            }
            else
            {
                CloseHandle(g_hChildStd_IN_Rd);
                CloseHandle(g_hChildStd_IN_Wr);
            }
        }
    }
票数 2
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35969730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档