獲取CMD執行結果——匿名管道


實現原理:

  管道是一種在進程間共享數據的機制,其實質是一段共享內存。Windows系統為這段共享的內存設計使用數據流I/O的方式來訪問。一個進程讀,另一個進程寫,這類似於一個管道的兩端,因此這種進程間的通信方式稱為“管道”。管道分為匿名管道和命名管道。匿名管道只能在父子進程間進行通信,不能在網絡間通信,而且數據傳輸是單向的,只能一端寫,另一端讀。命名管道可以在任意進程間通信,通信是雙向的,任意一端都可讀可寫,但是在同一時間只能有一端讀、一端寫。創建命名管道的方式可以獲取CMD執行結果的輸出內容

實現過程:

  (1).調用函數CreatePipe創建匿名管道,獲取管道數據讀取句柄和管道數據寫入句柄。

  (2).創建新進程(進程屬性為窗口隱藏、窗口的緩存句柄設置為上面得到的管道數據寫入句柄)

  (3).調用函數WaitForSingleObject等待命令執行完畢

  (4).調用ReadFile函數根據匿名管道的數據讀取句柄從匿名管道的緩沖區中讀取數據

  (5).關閉句柄,釋放資源

實現代碼:

    //************************************
    // 函數名:CCmdDlg::PipeCmd
    // 返回類型:BOOL
    // 功能:    執行CMD命令, 並獲取執行結果數據
    // 參數1:char *pszCmd    cmd命令
    // 參數2:char *pszResultBuffer    接收CMD結果的緩沖區
    // 參數3:DWORD dwResultBufferSize    緩沖區大小(緩沖區要大點,不然接收到的結果不全)
    //************************************
BOOL CCmdDlg::PipeCmd(char *pszCmd, char *pszResultBuffer, DWORD dwResultBufferSize)
{
    SECURITY_ATTRIBUTES securityAttributes = { 0 };
    // 設定管道的安全屬性
    securityAttributes.bInheritHandle = TRUE;
    securityAttributes.nLength = sizeof(securityAttributes);
    securityAttributes.lpSecurityDescriptor = NULL;

    // 創建匿名管道
    HANDLE hReadPipe = NULL;
    HANDLE hWritePipe = NULL;
    BOOL bRet = ::CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0);
    if (FALSE == bRet)
    {
        MessageBox(_T("CreatePipe Error"));
        return FALSE;
    }

    STARTUPINFO si = { 0 };
    // 設置新進程參數
    si.cb = sizeof(si);
    si.hStdError = hWritePipe;
    si.hStdOutput = hWritePipe;
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    // 創建新進程執行命令, 將執行結果寫入匿名管道中
    PROCESS_INFORMATION pi = { 0 };
    USES_CONVERSION;
    bRet = ::CreateProcess(NULL, A2W(pszCmd), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    if (FALSE == bRet)
    {
        MessageBox(_T("CreateProcess Error"));
    }

    // 等待命令執行結束
    ::WaitForSingleObject(pi.hThread, INFINITE);
    ::WaitForSingleObject(pi.hProcess, INFINITE);

    // 從匿名管道中讀取結果到輸出緩沖區
    ::RtlZeroMemory(pszResultBuffer, dwResultBufferSize);
    ::ReadFile(hReadPipe, pszResultBuffer, dwResultBufferSize, NULL, NULL);

    // 關閉句柄, 釋放內存
    ::CloseHandle(pi.hThread);
    ::CloseHandle(pi.hProcess);
    ::CloseHandle(hWritePipe);
    ::CloseHandle(hReadPipe);

    return TRUE;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM