Windows程式通訊之一看就懂的匿名管道通訊

iBinary發表於2019-05-30

程式通訊之一看就懂的匿名管道通訊

一丶匿名管道

1.1何為匿名管道

匿名管道是用來父程式跟子程式通訊的.還有一種是命名管道.不需要父子程式就可以進行通訊的.今天先說匿名管道的.
匿名管道. 就是父程式建立子程式. 讀取子程式資料.或者給子程式傳送資料.當然子程式也可以給父程式傳送資料.以及讀取父程式傳送過來的資料.

1.2建立匿名管道需要注意的事項

建立匿名管道,首先你要明白什麼是管道. 管道你可以想象成一個管子.
我們通過這個管子傳送資料.
如下圖所示:
Windows程式通訊之一看就懂的匿名管道通訊

通過上圖,我們就知道其實建立了兩個管道. 分別是父程式讀取的管道.以及
子程式讀取的管道.相應的.子程式也可以對父程式讀取的管道進行傳輸資料.父程式就可以讀取了.
這段話可能難以理解.你可以這樣想.

我父程式讀取子程式使用第一個管道. 那麼反正子程式寫的話也是使用第一個管道.因為子程式寫.我們父程式才能讀.

1.3 建立匿名管道需要的步驟

首先你需要了解建立匿名管道的API

WINBASEAPI
BOOL
WINAPI
CreatePipe(
    _Out_ PHANDLE hReadPipe,
    _Out_ PHANDLE hWritePipe,
    _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
    _In_ DWORD nSize
    );

關於這個API很簡單.相比你過來看匿名管道.說明你已經知道這個API了.
只不過不知道管道概念.(我猜的);

這個API很簡單.就是建立管道. 兩個控制程式碼.讀取控制程式碼跟寫入控制程式碼.
我們需要建立兩個管道.

還需要注意的是,父程式建立子程式,必須讓父程式控制程式碼可繼承.這個就是第三個屬性.安全屬性描述符中給即可.

那麼說一下建立步驟吧.

1.建立一個安全屬性描述符,設定控制程式碼可繼承
2.建立兩個管道. 父讀->子寫 子讀->父寫的
3.重定向輸出,將子程式的讀 以及子程式的寫重定向.
4.建立子程式
5.讀取\寫入資料給子程式.

1.4程式碼例子

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>





int main()
{

    HANDLE hParentRead, hParentWrite, hChildRead, hChildWrite; //建立4個控制程式碼

    STARTUPINFO si = { 0 };                         //啟動資訊結構體
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi = { 0 };                 //程式資訊結構體

    DWORD dwWritedBytes = 0;
    DWORD dwReadedBytes = 0;

    DWORD dwBytesRead = 0;
    DWORD dwTotalBytesAvail = 0;
    DWORD dwBytesLeftThisMessage = 0;

    SECURITY_ATTRIBUTES sa = { 0 };                //安全屬性描述符        
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;                      //設定控制程式碼可繼承

    //建立管道1. 父程式讀 -> 子程式寫入
    BOOL bRet = CreatePipe(&hParentRead,
        &hChildWrite,
        &sa,
        0);

    //建立管道2.  子程式讀->父程式寫.
    bRet = CreatePipe(&hChildRead,
        &hParentWrite,
        &sa,
        0);

    //這裡將子程式寫重定向到 stdout中. 子程式讀取重定向到stdinput中
    si.hStdInput = hChildRead;    
    si.hStdOutput = hChildWrite;
    si.dwFlags = STARTF_USESTDHANDLES;   //設定視窗隱藏啟動

    

    bRet = CreateProcess(NULL,
        "cmd.exe",                      //建立cmd程式.預設尋找cmd程式.
        NULL,
        NULL,
        TRUE,
        CREATE_NO_WINDOW,
        NULL,
        NULL,
        &si,
        &pi);

    char szBuffer[15] = "calc \n";
    WriteFile(hParentWrite, szBuffer, 15, NULL, 0);//使用writeFile操作管道,給cmd傳送資料命令.
    return 0;
}

1.5程式碼執行截圖

Windows程式通訊之一看就懂的匿名管道通訊

相關文章