CreateProcess創建進程踩過的坑(路徑中含有空格以及路徑反斜槓太少)

最近項目中踩到了兩個坑:

一個是CreateProcess中參數含有路徑,但是沒有使用雙引號引起來。

一個是CreateProcess中路徑沒有使用4個反斜槓,只是用了2個導致命令行解析錯誤。

 

(1)路徑含有空格

這個問題應該比較簡單的,也很好測試出來,在XP系統上很多路徑都會帶有空格,只需要在含有路徑的參數上加上雙引號即可。

const int cmdlineBufferMaxLength = 8190;

WCHAR szCmdLine[cmdlineBufferMaxLength + 1] = { 0 };

std::wstring strPathParam = L"C:\\Program Files\\Windows NT\\";

StringCchPrintf(szCmdLine, cmdlineBufferMaxLength, L"d:\\CreateProcessDemo.exe --pathparam=\"%s\"", strPathParam.c_str());

CreateProcessW(NULL, (LPTSTR)szCmdLine, NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo));

注意上方代碼標紅的雙引號。

 

(2)參數中含有路徑,導致命令行解析錯誤

const int cmdlineBufferMaxLength = 8190;

WCHAR szCmdLine[cmdlineBufferMaxLength + 1] = { 0 };

std::wstring strPathParam = L"D:\\unit_tests\\";

StringCchPrintf(szCmdLine, cmdlineBufferMaxLength, L"d:\\CreateProcessDemo.exe --pathparam=\"%s\" --otherparam=xxx", strPathParam.c_str());

CreateProcessW(NULL, (LPTSTR)szCmdLine, NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo);

 

你們看這個代碼有問題嗎?可以自己寫代碼驗證一下,確實是有問題的。

問題就在於代碼代碼最終生成的szCmdLine是這樣子的:

d:\CreateProcessDemo.exe --pathparam="D:\unit_tests\" --otherparam=xxx

這個命令行中最後的一個反斜槓在CreateProcessDemo進程中會當做代碼使用,最終就變成了下面這樣

\" 就被轉移成雙引號,作爲整個字符串的一部分了,導致後面的參數--otherparam=xxx沒有被解析出來。

 

CreateProcessDemo中是這樣寫代碼驗證的:
        int num_args = 0;
        wchar_t** args = NULL;
        args = ::CommandLineToArgvW(GetCommandLineW(), &num_args);

 

所以正確的做法是把strPathParam變量定義改成這樣:

std::wstring strPathParam = L"D:\\\\unit_tests\\\\";

bug就這樣解決了。

 

後面自己又測試了下,發現如果路徑中沒有最後一個反斜槓也是沒有問題的,類似這樣:

std::wstring strPathParam = L"D:\\unit_tests";

因爲沒有那個轉移雙引號的邏輯了。

雖然可以成功,但是嚴謹,確保萬無一失還是在路徑中加入四個反斜槓吧。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章