[英]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 但程序剛剛退出並且沒有帶有子進程的彈出窗口,即使它在后台運行我也無法寫入它。
根據您表示的代碼,發現了兩個問題:
CreateProcessA
的bInheritHandles
參數設置為TRUE
而不是NULL
使調用進程中的每個可繼承句柄都被新進程繼承(這里是cmd.exe
)。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.