Qt5.9呼叫Windows的匿名管道總結
阿新 • • 發佈:2018-12-16
本部落格主要總結在Qt下呼叫Windows系統函式CreatePipe()建立一個管道,然後啟動一個程序。該程序的輸出連線管道的寫端寫入資料。然後呼叫Windows系統函式ReadFile()連線管道的讀埠,讀取管道的內容,然後返回該內容。
1.1具體的封裝函式總結如下:
QString executeCmd(QString cmdLine) { //建立匿名管道 HANDLE hReadPipe, hWritePipe; SECURITY_ATTRIBUTES safety; //安全屬性 safety.nLength = sizeof(SECURITY_ATTRIBUTES); //結構體大小 safety.lpSecurityDescriptor = NULL; //安全描述符,NULL;使用預設的 safety.bInheritHandle = TRUE; //安全描述符的物件能否被子程序繼承 if (!CreatePipe(&hReadPipe, &hWritePipe, &safety, 0)) { //建立管道錯誤 return QString(tr("建立管道錯誤!")); } //建立程序 TCHAR *cmdStr = QStringToTChar(cmdLine); qDebug()<<"cmdStr=="<<cmdStr; STARTUPINFO startupInfo = { sizeof(startupInfo) }; //程序資訊 startupInfo.hStdError = hWritePipe; //標誌控制檯視窗快取 startupInfo.hStdOutput = hWritePipe; //標誌控制檯視窗快取 startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //使用wSHOWWIndows成員 startupInfo.wShowWindow = SW_HIDE; PROCESS_INFORMATION pinfo; if (!CreateProcess(NULL, cmdStr, NULL, NULL, TRUE, NULL, NULL, NULL, &startupInfo, &pinfo)) { //建立程序錯誤 return QString(tr("建立程序錯誤!")); } CloseHandle(hWritePipe); //獲取管道資訊 char buffer[4096]; memset(buffer, 0, 4096); DWORD byteRead; QString output; //返回值 while (true) { if (ReadFile(hReadPipe, buffer, 4095, &byteRead, NULL) == NULL) { break; } qDebug()<<"buffer=="<<buffer; output.append(QString::fromUtf8(buffer)); //char*轉QString } CloseHandle(hReadPipe); return output; }
TCHAR *QStringToTChar(const QString &str) { QByteArray ba = str.toUtf8(); char *data = ba.data(); //以上兩步不能直接簡化為“char *data = str.toUtf8().data();” int charLen = strlen(data); int len = MultiByteToWideChar(CP_ACP, 0, data, charLen, NULL, 0); TCHAR *buf = new TCHAR[len + 1]; MultiByteToWideChar(CP_ACP, 0, data, charLen, buf, len); buf[len] = '\0'; return buf; }
函式QString executeCmd(QString cmdLine)的功能是輸入cmd命令列,輸出命令列執行結果。(有一個bug,輸出內容中文顯示亂碼) 函式TCHAR *QStringToTChar(const QString &str)的功能是將QString轉為TCHAR。
1.2函式呼叫例項
由於把函式executeCmd()變為一個單例類的成員函式,所以呼叫方法如下。
qDebug()<<QGlobalClass::GetInstance()->executeCmd("ipconfig /?");
1.3程式執行結果如下圖所示
參考內容: