【发布时间】:2018-12-03 12:15:31
【问题描述】:
我正在使用msdn creating child process 中的文章,因为它非常接近我想要实现的目标。
creating a child process c#,redirection using pipes中的问题 确实在我的方法中发现了一些错误,但很有可能比我能找到的错误更多。
我正在尝试使用管道在父进程和子进程之间创建连接,在这些管道中它们能够相互读写 StdOut。在我的解决方案中,我创建了两个名为 ParentTalk 和 ChildTalk 的控制台应用程序。
据我所知,子进程没有运行我为其创建的代码,因此我可能错误地创建了子进程
父.cpp
#include <windows.h>
#include "pch.h"
#include <iostream>
#include <stdio.h>
HANDLE childInRead = NULL;
HANDLE childInWrite = NULL;
HANDLE childOutRead = NULL;
HANDLE childOutWrite = NULL;
HANDLE parentInRead = NULL;
#define BUFSIZE 4096
void CreateChildProcess() {
TCHAR applicationName[] = TEXT("ChildTalk.exe");
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL success = FALSE;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdError = childInRead;
si.hStdOutput = childInRead;
si.hStdInput = childOutWrite;
si.dwFlags |= STARTF_USESTDHANDLES;
success = CreateProcess(NULL, applicationName, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!success) {
printf("Error creating child process \n");
}
else {
printf("Child process successfuly created \n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
int main()
{
printf("Parent process running.... \n");
DWORD dRead, dWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
SECURITY_ATTRIBUTES secAttr;
secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
secAttr.bInheritHandle = TRUE;
secAttr.lpSecurityDescriptor = NULL;
printf("Creating first pipe \n");
if (!CreatePipe(&parentInRead, &childInWrite, &secAttr, 0)) {
printf("\n error creating first pipe \n");
}
printf("Creating second pipe \n");
if (!CreatePipe(&childOutWrite, &childOutRead, &secAttr, 0)) {
printf("\n error creating second pipe \n");
}
if (!SetHandleInformation(parentInRead, HANDLE_FLAG_INHERIT, 0)) {
printf("\n parentInRead SetHandleInformation \n");
}
if (!SetHandleInformation(childInWrite, HANDLE_FLAG_INHERIT, 0)) {
printf("\n childInWrite SetHandleInformation \n");
}
childOutRead = GetStdHandle(STD_OUTPUT_HANDLE);
parentInRead = GetStdHandle(STD_INPUT_HANDLE);
printf("\n Creating child process..... \n");
CreateChildProcess();
for (;;){
printf("Inside for loop \n");
bSuccess = ReadFile(parentInRead, chBuf, BUFSIZE, &dRead, NULL);
if (!bSuccess) {
printf("error reading \n");
break;
}
bSuccess = WriteFile(childInWrite, chBuf,
dRead, &dWritten, NULL);
if (!bSuccess) {
printf("error writing \n");
break;
}
}
return 0;
}
ChildTalk.cpp
#include <windows.h>
#include <stdio.h>
#include "pch.h"
#define BUFSIZE 4096
int main()
{
DWORD dRead, dWritten;
CHAR chBuf[BUFSIZE];
BOOL success = FALSE;
HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
printf("Child process running....");
if (stdIn == INVALID_HANDLE_VALUE || stdOut == INVALID_HANDLE_VALUE) {
ExitProcess(1);
}
for (;;) {
success = ReadFile(stdIn, chBuf, BUFSIZE, &dRead, NULL);
if (!success || dRead == 0) break;
success = WriteFile(stdOut, chBuf, dRead, &dWritten, NULL);
if (!success) break;
}
return 0;
}
EDIT1:运行代码时没有错误,程序停留在
bSuccess = WriteFile(childStdOut, chBuf,
dRead, &dWritten, NULL);
if (!bSuccess) {
printf("error writing");
break;
}
因为它正在等待输入,但是当我输入任何内容时,它会打印“错误写入”消息。我添加到子代码“正在运行的子进程...”的消息未打印
EDIT2:更改了代码,因为我认为句柄不正确,现在它正在打印“内部 for 循环”,但仍然没有子进程。需要先启动子进程的控制台应用吗?
【问题讨论】:
-
你得到什么输出?请edit您的问题并在那里进行说明
-
双方先致电
ReadFile之前 antWriteFile。因为您使用 同步 文件 - 您从双方都挂在电话ReadFile中。您需要或使用异步管道(最好的)或协调读/写操作。严格按照顺序进行。同样在异步管道的情况下 - 你不需要创建 2 个管道对(4 个句柄)。足够创建单个管道对(仅 2 个句柄 - 1 个在父级和一个在子级)并将此管道用于读取和写入 -
你想要什么?你必须在
ReadFile电话中挂在两边 -
@RbMm 我想要完成的是在孩子的 StdOut 上显示在父母的 StdIn 上写的内容,并在父母的 StdOut 上显示在孩子的 StdIn 上写的内容。子进程代码有一个错误,因为我正在读取孩子的 StdIn 中的内容并将其写入孩子的 StdOut
-
@KushQQ 为子进程打开一个新的控制台,你应该使用标志
CREATE_NEW_CONSOLE:CreateProcess(NULL, applicationName, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
标签: c++ windows winapi process