我已经按照示例here从管道读取,但ReadFile失败,GetLastError()显示管道坏了。
我已经在程序的早期创建并使用了(成功)一个管道,但我关闭了所有的句柄,并为新管道使用了全新的变量,以确保。
任何想法为什么这不起作用?
HANDLE g_hChildStd_OUT_Rd2 = NULL;
HANDLE g_hChildStd_OUT_Wr2 = NULL;
SECURITY_ATTRIBUTES saAttr2;
STARTUPINFO si2;
PROCESS_INFORMATION pi2;
ZeroMemory( &si2, sizeof(si2) );
si2.cb = sizeof(si2);
ZeroMemory( &pi2, sizeof(pi2) );
//create pipe
saAttr2.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr2.bInheritHandle = TRUE;
saAttr2.lpSecurityDescriptor = NULL;
CreatePipe(&g_hChildStd_OUT_Rd2, &g_hChildStd_OUT_Wr2, &saAttr2, 0);
//create child process
bSuccess = FALSE;
memset(szCmdLine, 0, MAX_PATH);
sprintf(szCmdLine, "ffmpeg.exe -i output.mp3");
ZeroMemory( &pi2, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &si2, sizeof(STARTUPINFO) );
si2.cb = sizeof(STARTUPINFO);
si2.hStdOutput = g_hChildStd_OUT_Wr2;
si2.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si2, &pi2);
//read from pipe
CloseHandle(g_hChildStd_OUT_Wr2);
memset(chBuf, 0, BUFSIZE);
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd2, chBuf, BUFSIZE, &dwRead, NULL);
[bSuccess is 0 and GetLastError() returns error 109]
........
答案 0 :(得分:3)
当另一端关闭管道时,“断管”是正常错误。在您的情况下,这意味着没有“另一端”,或者其他应用程序没有向其stdout
写入任何内容。
我已将您的代码修改为可编译的测试用例 - 有两种情况ReadFile
在没有为我读取任何数据的情况下失败:
CreateProcess
失败了。我添加了assert
,以便可以识别问题。这当然会导致管道破裂。stderr
重定向到了管道,正如我的echo
示例所示,这将在管道的另一端接收两个流。代码:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define BUFSIZE 200
int main(void)
{
BOOL bSuccess;
char szCmdLine[MAX_PATH];
char chBuf[BUFSIZE];
DWORD dwRead;
HANDLE g_hChildStd_OUT_Rd2 = NULL;
HANDLE g_hChildStd_OUT_Wr2 = NULL;
SECURITY_ATTRIBUTES saAttr2;
STARTUPINFO si2;
PROCESS_INFORMATION pi2;
ZeroMemory( &si2, sizeof(si2) );
si2.cb = sizeof(si2);
ZeroMemory( &pi2, sizeof(pi2) );
//create pipe
saAttr2.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr2.bInheritHandle = TRUE;
saAttr2.lpSecurityDescriptor = NULL;
assert(CreatePipe(&g_hChildStd_OUT_Rd2, &g_hChildStd_OUT_Wr2, &saAttr2, 0));
//create child process
bSuccess = FALSE;
memset(szCmdLine, 0, MAX_PATH);
sprintf(szCmdLine, "cmd /c echo output && echo error>&2");
ZeroMemory( &pi2, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &si2, sizeof(STARTUPINFO) );
si2.cb = sizeof(STARTUPINFO);
si2.hStdOutput = g_hChildStd_OUT_Wr2;
si2.hStdError = g_hChildStd_OUT_Wr2; // also add the pipe as stderr!
si2.dwFlags |= STARTF_USESTDHANDLES;
assert(CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si2, &pi2));
//read from pipe
CloseHandle(g_hChildStd_OUT_Wr2);
memset(chBuf, 0, BUFSIZE);
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd2, chBuf, BUFSIZE, &dwRead, NULL);
printf("%d %lu 0x%08lx\n", bSuccess, dwRead, GetLastError());
if (bSuccess)
printf("\t'%*s'\n", (int)dwRead, chBuf);
else
break;
}
return 0;
}