我正在尝试使用重定向的stdin / stdout创建一个子进程。
我正在创建一个管道来重定向标准输入并将标准输出写入文件。
这是我尝试过的
#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时,它可以工作。另外,正如预期的那样,使用我的管道客户端对其进行写入无法正常工作,因此无法获取该管道的句柄。
CreateFile始终为true,并且句柄值似乎有效,GetLastError()返回0,但程序仅退出且子进程没有弹出窗口,即使它在后台运行也无法写入。
最佳答案
根据您表示的代码,发现两个问题:
bInheritHandles
的CreateProcessA
参数设置为TRUE
而不是NULL
,以使调用进程中的每个可继承句柄都被新进程继承(这里是cmd.exe
)。 cmd.exe
在启动和退出后显示版本信息。如果要阻止它退出,可以为cmd.exe
设置命令行以使其连续运行。 小费:
函数失败后立即调用
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;
}
关于c++ - 通过将标准输入/输出重定向到管道来制作子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62095603/