所以我在尝试重定向进程的输出时遇到了一个奇怪的问题。我创建了一个示例程序,它首先打印一个语句,然后在5秒后打印另一个语句。
我通过CreateProcesss
设置我的流程,并通过CreatePipe
等设置我的管道,这是所有必须做的正常事情。我确保在创建后关闭进程的OUT写入和IN rd管道。我使用PeekNamedPipe
来确定是否有要读取的数据。完成所有这些初始设置之后,直到5秒钟结束后我才会收到任何输出。它只会在进程退出后向我返回数据。我似乎无法弄明白为什么。
想知道我的逻辑是否有人看错了什么?
我有以下c代码:
#include <windows.h>
#include <stdio.h>
int main(){
// the handles for creating pipes
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_Err_Rd = NULL;
HANDLE g_hChildStd_Err_Wr = NULL;
// security attributes for inheriting pipe handles
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
printf("StdoutRd CreatePipe");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
printf("Stdout SetHandleInformation");
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
printf("Stdin CreatePipe");
// Ensure the write handle to the pipe for STDIN is not inherited.
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
printf("Stdin SetHandleInformation");
// Create a pipe for the child process's STDERR.
if ( ! CreatePipe(&g_hChildStd_Err_Rd, &g_hChildStd_Err_Wr, &saAttr, 0) )
printf("StdoutRd CreatePipe");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_Err_Rd, HANDLE_FLAG_INHERIT, 0) )
printf("Stdout SetHandleInformation");
STARTUPINFO si={0};
ZeroMemory( &si, sizeof(STARTUPINFO) );
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;
PROCESS_INFORMATION pi={0};
int status = CreateProcessA("a.exe", 0, 0, 0, TRUE, 0, 0, 0, &si, &pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// Dont forget to close stderr once we make it. Currently stderr gets combined
// with stdout
CloseHandle(g_hChildStd_OUT_Wr);
CloseHandle(g_hChildStd_IN_Rd);
while (1 )
{
Sleep(200);
DWORD dwRead = 0;
unsigned char out[5] = {0};
PeekNamedPipe(g_hChildStd_OUT_Rd,0,0,0,&dwRead,0);
if (dwRead > 0)
{
ReadFile(g_hChildStd_OUT_Rd,out, 5 ,&dwRead, 0);
printf("STDOUT: %s", out);
}
printf("write file\n");
WriteFile(g_hChildStd_IN_Wr,"hello\n\n",7,&dwRead,0);
}
}
在以下程序a.exe上进行测试:
#include <stdio.h>
#include <windows.h>
int main()
{
char word[250];
printf("HELLO WORLD: ");
Sleep(500);
printf("\nyou printed %s!\n\n",word);
Sleep(5000);
printf("More prints..\n");
return 0;
}