1. 程式人生 > >Qt5.9呼叫Windows的匿名管道總結

Qt5.9呼叫Windows的匿名管道總結

本部落格主要總結在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程式執行結果如下圖所示

參考內容: