簡體   English   中英

使用重定向的標准輸入/輸出創建一個子進程到 pipe

[英]Making a child process with redirected standard input/output to a pipe

我正在嘗試使用重定向的 stdin/stdout 創建一個子進程。 我正在創建一個 pipe 來重定向標准輸入並將標准輸出寫入文件。

這是我嘗試過的

#include <Windows.h>
#include <iostream>

int main()
{
    STARTUPINFOA sInfo;
    PROCESS_INFORMATION pInfo;
    SECURITY_ATTRIBUTES sAttr;
    ZeroMemory(&sInfo, sizeof(sInfo));
    ZeroMemory(&pInfo, sizeof(pInfo));
    ZeroMemory(&sAttr, sizeof(sAttr));
    sInfo.cb = sizeof(sInfo);
    sAttr.bInheritHandle = true;
    HANDLE fileTest = CreateFileA("hello.txt", GENERIC_READ | GENERIC_WRITE, 0, &sAttr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE stdinPipe = CreateNamedPipeA("\\\\.\\pipe\\DokiDokiIn", PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, &sAttr);
    sInfo.hStdInput = stdinPipe;
    sInfo.hStdOutput = fileTest;
    sInfo.hStdError = fileTest;
    sInfo.dwFlags |= STARTF_USESTDHANDLES;
    char cmdLine[] = "cmd.exe";
    bool success = CreateProcessA("C:\\WINDOWS\\system32\\cmd.exe", NULL, &sAttr, NULL, NULL, NULL, NULL, NULL, &sInfo, &pInfo);
    if (!success) {
        std::cout << "CreateProcessA() failed with error " << GetLastError() << "\n";
    }
    std::cout << GetLastError() << "\n";
    return 0;
}

這似乎不起作用,每當我將STARTF_USESTDHANDLES指定為 dwFlags 時,打開的進程會立即關閉(或者根本不打開,不確定)。 當我沒有指定標志但沒有重定向 I/O 時,它可以工作。 此外,正如預期的那樣,使用我的 pipe 客戶端寫入它不起作用,它無法處理該 pipe。 CreateFile 始終為 true 並且句柄值似乎有效,GetLastError() 返回 0 但程序剛剛退出並且沒有帶有子進程的彈出窗口,即使它在后台運行我也無法寫入它。

根據您表示的代碼,發現了兩個問題:

  1. CreateProcessAbInheritHandles參數設置為TRUE而不是NULL使調用進程中的每個可繼承句柄都被新進程繼承(這里是cmd.exe )。
  2. cmd.exe啟動退出后顯示版本信息。 如果您想阻止它退出,您可以為cmd.exe設置命令行使其連續運行。

小費:

在 function 失敗后立即調用GetLastError()否則錯誤代碼可能被其他函數設置zero

以下是我的一個示例工作。 你可以試一試。

int main()
{
    STARTUPINFOA sInfo;
    PROCESS_INFORMATION pInfo;
    SECURITY_ATTRIBUTES sAttr;
    ZeroMemory(&sInfo, sizeof(sInfo));
    ZeroMemory(&pInfo, sizeof(pInfo));
    ZeroMemory(&sAttr, sizeof(sAttr));
    sInfo.cb = sizeof(sInfo);
    sAttr.bInheritHandle = true;
    HANDLE fileTest = CreateFileA("hello.txt", GENERIC_READ | GENERIC_WRITE, 0, &sAttr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE stdinPipe = CreateNamedPipeA("\\\\.\\pipe\\DokiDokiIn", PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, &sAttr);
    sInfo.hStdInput = stdinPipe;
    sInfo.hStdOutput = fileTest;
    sInfo.hStdError = fileTest;
    sInfo.dwFlags |= STARTF_USESTDHANDLES;

    char input[] = "ping www.google.com -t";
    char cmd[] = "cmd.exe";
    // initialize cmd
    char cmdline[MAX_PATH];
    sprintf_s(cmdline, sizeof(cmdline), "%s /c %s", cmd, input);
    bool success = CreateProcessA("C:\\WINDOWS\\system32\\cmd.exe", cmdline, &sAttr, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);
    if (!success) {
        DWORD errCode = GetLastError();
        std::cout << "CreateProcessA() failed with error " << errCode << "\n";
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM