你是否好奇過,為什麼某些安裝程式能在無視窗的情況下呼叫像 PKZIP 這類主控台工具,並將輸出完美導向自家的文字方塊?答案就是「匿名管道」。本文從熟悉的 DOS 管道符號 | 切入,深入淺出講解 Win32 匿名管道的建立、繼承機制與實戰應用。
在命令提示字元下,type autoexec.bat | more 利用管道將前一指令的標準輸出導向後一指令的標準輸入。這正是管道「生產者-消費者」模型的經典體現。
Windows 提供 CreatePipe 函數建立管道:
BOOL CreatePipe(
PHANDLE hReadPipe, // 讀取端控制代碼指標
PHANDLE hWritePipe, // 寫入端控制代碼指標
LPSECURITY_ATTRIBUTES lpPipeAttributes, // 安全屬性(決定是否可被子行程繼承)
DWORD nSize // 緩衝區大小,0 表由系統決定
);
關鍵點: 前兩個參數是「指向控制代碼的指標」,而非控制代碼本身——這是新手常犯的錯誤。
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; // 結構大小
LPVOID lpSecurityDescriptor; // 安全描述子
BOOL bInheritHandle; // 控制代碼是否可被子行程繼承
} SECURITY_ATTRIBUTES;
要讓子行程(如被呼叫的解壓縮程式)能使用管道,必須將 bInheritHandle 設為 TRUE,並在 CreateProcess 的 STARTUPINFO 中指定 hStdOutput / hStdInput 為管道的寫入/讀取端。
CreatePipe(&hRead, &hWrite, &sa, 0),sa.bInheritHandle = TRUE。hWrite,主程式持有 hRead。ReadFile(hRead, ...) 讀取資料,顯示於 UI 元件中。這項技術廣泛應用於安裝程式、IDE 輸出視窗、自動化測試工具等場景,是 Windows 進程間通訊(IPC)的基石之一。