1. 程式人生 > 其它 >通過匿名管道獲得CMD或其它程式的輸出(不彈窗)

通過匿名管道獲得CMD或其它程式的輸出(不彈窗)

技術標籤:c++

寫程式時候 需要呼叫CMD並獲得CMD輸出結果.

我使用VS2019.

最簡單的方法 是用 _popen() … 但在非控制檯程式下 ,它彈窗 ,一閃而過. 網上查了很多資料 都說沒辦法靜默執行.
還有一套方法是WIN32 的 CreatePipe + CreateProcess

雖說這裡是原創, 但也借鑑了很多文章. 無奈的是,程式碼基本都執行不起來. 要麼就雲裡霧裡, 讓我這小白看不懂…
折騰了有3-4天…弄出來了, 分享完整程式碼.註釋… 給同學們參考 少走彎路. 有可以改進的地方 請指教.
右邊是目前我找到最好的一篇文章了, 講得清楚 感謝老師. https://write-bug.com/article/1932.html

呼籲大家得閒時 把填過的坑,提煉過的內容,分享出來. 增加咱們網路文章含金量. 別一起苦哈哈的重複造輪子…這簡單的東西愣是沒找到適合的解決方案. 多一點點的付出, 在網路時代, 勝造七級浮屠. ヽ(ー_ー)ノ

PS :真不知道 應該使用char還是wchar_t 看的資料也眾說紛紜. 但就自己的使用體驗, 平時用char 需要時候轉wchar_t
就比如下面的程式碼, 如果GetAppOutput返回值是寬字串 那麼main函式中 列印的是%ws 寬字元, 會沒法顯示管道讀取的內容… 不知道為什麼. 但%s可以(即使GetAppOutput返回值是寬字串)… 是什麼原因呢?

#include
<Windows.h>
#include <stdio.h> char* GetAppOutput(const char* pszCmdLine, const unsigned& nResultBufferSize) { //在編譯前 可能根據需求調整陣列大小的變數 char szResultBuffer[3000] = ""; //返回字串的尺寸 wchar_t szCmdLine[300] = L""; //傳參傳遞的輸入命令及尺寸賦值到新陣列. CreateProcess函式不識別const和多位元組字元.
mbstowcs(szCmdLine, pszCmdLine, sizeof(szCmdLine) * 0.5); //多位元組字串轉寬字串 //設定安全屬性 SECURITY_ATTRIBUTES sa = { 0 }; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; //建立匿名管道 HANDLE hRead = NULL; HANDLE hWrite = NULL; if (!CreatePipe(&hRead, &hWrite, &sa, 0)) { MessageBoxW(NULL, L"CreatePipe錯誤", L"提示", MB_ICONERROR); exit(0); } //設定新程序引數 PROCESS_INFORMATION pi = { 0 }; //新程序結構體 STARTUPINFO si = { 0 }; //指定新程序的主視窗特性 si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //標記出需要控制的內容 si.wShowWindow = SW_HIDE; //隱藏視窗 si.hStdError = hWrite; si.hStdOutput = hWrite; //建立新程序, 將執行結果寫入匿名管道中 if (!CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { MessageBoxW(NULL, L"CreateProcess錯誤", L"提示", MB_ICONERROR); exit(0);; } //等待命令執行完畢 WaitForSingleObject(pi.hThread, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE); //讀取匿名管道的輸出結果到緩衝區 RtlZeroMemory(szResultBuffer, nResultBufferSize); ReadFile(hRead, szResultBuffer, nResultBufferSize, NULL, NULL); //關閉控制代碼 CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(hWrite); CloseHandle(hRead); //返回結果 return szResultBuffer; } int main() { printf("---------cmd輸出---------\n%s\n", GetAppOutput("cmd /c getmac", 1000)); printf("---------PowerShell輸出--\n%s", GetAppOutput("PowerShell Get-Date", 1000)); return 0; }