2012-03-13 24 views
1

我試圖使用devcon.exe來檢查各種硬件的狀態。在這個例子中,我試圖檢查我的SATA HBA狀態,但devcon對此抱怨。這裏的代碼:被傳遞給CreateProcess的參數沒有像我預期的那樣被解析

int main(int argc, char** argv) { 
    std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00"); 

    char* pCmdLine(new char[cmdLine.length() + 10]); 
    memset(pCmdLine, 0, cmdLine.length() + 10); 

    for(int i(0); i < cmdLine.length(); i++) 
     pCmdLine[i] = cmdLine.at(i); 

    STARTUPINFO si = { sizeof(STARTUPINFO) }; 
    PROCESS_INFORMATION pi = {0}; 

    if(!CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { 
     std::cout << "Create child process failed. Error code: " 
        << GetLastError() << std::endl; 
     return 1; 
    } 

    WaitForSingleObject(pi.hProcess, INFINITE); 
    CloseHandle(pi.hThread); 
    CloseHandle(pi.hProcess); 

    return 0; 
} 

問題是,當上述執行,devcon抱怨,「找不到匹配的設備。」但是,如果我將該命令行從調試器複製/粘貼到我的命令提示符中,並按下回車鍵(或刪除調試器放置的所有包含引號的內容),該命令將按預期完美執行。

我在遞送字符串時出現了什麼問題?以上內容是閱讀MSDN上的CreateProcess()文檔的結果(發現第一個參數不一定需要,而cmd參數根本不應該存在)。我分配10個額外字節的內存來複制字符串的原因是爲了使CreateProcess()函數的內容中的「任何」可以改變,而不會跺住其他內存。至少,當我這樣做時,這是我的想法。

+0

無關,但你泄漏內存,爲什麼在地球上一個用'memset'而不是一個簡單的'()'? – ildjarn 2012-03-13 19:17:21

回答

5

Command line metacharacters are parsed by the command processor。特別是您使用^來防止CMD.EXE破壞和號處的命令。但是你直接執行程序,繞過CMD.EXE。因此,^傳遞給devcon.exe誰讓他們感到困惑。

解決方法:刪除^個字符。

您的問題實際上與您的標題相反。您傳遞給CreateProcess的命令行正在按照您指定的直接傳遞到應用程序

+0

謝謝!這就對了。我應該如何修改標題以獲得更好的參考? – 2012-03-13 20:40:07

0

你可以嘗試這樣的:

1
std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00 

想必^插入符中有來自於命令行解釋器,在那裏他們服務關閉的&特殊含義輸入的命令的殘留物。

只需刪除插入符號。

另請注意,您當前的代碼泄漏內存。

爲了避免這種情況,

string commandLineArg = cmdLine + '\0'; 

... CreateProcess(0, &commandLineArg[0], ...) 
+0

我覺得很愚蠢。我錯過了刪除[]緩衝區的失敗。這是一個簡單的程序,我正在用它來調試這個代碼中較大的問題。我實際上刪除了那裏的記憶。不過,我認爲這種方法更加優雅。感謝您的建議。 – 2012-03-13 20:43:32

0

我用:

TCHAR var[] = _T(" C:\\filepathe\\foo");

CreateProcess(NULL, var,...); 
相關問題