2011-01-26 69 views
1

我按照示例here從管道讀取,但ReadFile失敗,並且GetLastError()顯示管道已損壞。
我已經在程序的早期創建並使用了(成功)一個管道,但是我關閉了所有的手柄,並且爲了確保新管道使用了全新的變量。
任何想法爲什麼這不起作用?Win32中的破損管道(WinAPI)

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] 
    ........ 
+1

請張貼最小但完整的源代碼,所以我們可以利用我們的編譯器來幫助查找問題。全=我們可以編譯並運行它。最小=只有足夠的代碼來重現您的問題 – 2011-02-23 11:57:37

回答

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; 
} 
+0

對不起,*非常*遲到接受,但我很難找到有問題的代碼,並看到實際上出了什麼問題。問題的確是被調用的可執行文件ffmpeg.exe沒有向stdout輸出任何內容。 – Claudiu 2012-02-14 22:19:42

相關問題