mar*_*000 6 c++ winapi stdin stdout pipe
我想做的是类似于Visual Studio在其输出窗口或其工具窗口中的其他编辑器中执行的操作:从我的进程A启动另一个进程B并捕获其stdout/stderr输出.
到目前为止,我得到了它CreatePipe(),但由于某种原因,B的输出在写入时没有到达B. 它的行为更像某种缓冲区被填满,当它已满时,所有缓冲区内容立即到达A. 我编写了自己的测试程序,输出了一些内容并fflush(stdout)直接执行了.然后输出直接到达A.但我不能改变我想用这种方式使用的所有B进程的代码.试图从A冲洗管道也不起作用.
这应该怎么样?
我的初始化代码以及使用代码:
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
err = CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, stdouthistory);
if (err == 0)
return 1;
err = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if (err == 0)
return 3;
CloseHandle(hChildStdoutRd);
DWORD a, b, c;
a = PIPE_READMODE_BYTE | PIPE_NOWAIT;
b = 0;
c = 0;
SetNamedPipeHandleState(hChildStdoutRdDup, &a, &b, &c);
err = CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa, stdinhistory);
if (err == 0)
return 1;
err = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if (err == 0)
return 4;
CloseHandle(hChildStdinWr);
a = PIPE_READMODE_BYTE | PIPE_NOWAIT;
b = 0;
c = 0;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOW;
si.hStdOutput = hChildStdoutWr;
si.hStdError = hChildStdoutWr;
si.hStdInput = hChildStdinRd;
ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
err = CreateProcess(0, this->cmdline, 0, 0, true, CREATE_NO_WINDOW, 0, 0, &si, &pi);
if (err == 0)
return 4;
Run Code Online (Sandbox Code Playgroud)
消费:
DWORD avail;
unsigned int ofs = 0;
if (PeekNamedPipe(hChildStdoutRdDup, NULL, 0, NULL, &avail, NULL))
{
if (avail != 0)
{
int err = ReadFile(hChildStdoutRdDup, s + ofs, slen, &threadbuffern, 0);
// Consume ...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我刚刚发现了这个问题:在Ruby中连续读取外部进程的STDOUT.这是同样的问题,但在Ruby的上下文中.可悲的是,解决方案是使用一些让它工作的Ruby库.那个图书馆是怎么做到的?Win32/C++中的等价物是什么?
你不能那样做。如果输出在有问题的进程中没有被刷新,那么它实际上并没有首先被写入标准输出。也就是说,操作系统实际上还没有从目标进程获取数据。
这不是管道的任何固有延迟,而是您正在监视的程序实际上尚未将其写入管道。
您应该注意到执行所述程序时命令提示符的行为完全相同,因为命令提示符使用与您正在使用的相同的管道解决方案。如果不这样做,那是因为相关程序检测到它们正在写入文件句柄,而不是控制台句柄,并进行额外的缓冲。