2017-02-10 57 views
0

當我使用ShellExecuteEx這樣的命令"-unused parameter -action capturescreenshot -filename C:\\ATDK\\Screenshots\\abcd.jbg"一切工作正常,Executor.exe開始char* argv[]具有所有約。 9個參數。但是當命令有更多的符號時,例如文件名是「abc ... xyz.jpg」,那麼該進程的argc == 1,該命令是空的。因此,發送到ShellExecute之前,命令是OK當我將其更改爲ShellExecute,而不是Ex,它的工作原理!命令可能很長,並且已成功通過。任何人都可以解釋有什麼區別?這是我填寫的SHELLEXECUTEINFO的代碼。ShellExecuteEx不通過長命令

std::wstringstream wss; 
wss << L"-unused" << " " // added because we need to pass some info as 0 parameter 
    << L"parameter" << " " // added because EU parser sucks 
    << L"-action" << " " 
    << L"capturescreenshot" << " " 
    << L"-filename" << " " 
    << L"C:\\ATDK\\Screenshots\\abc.jpg"; 

SHELLEXECUTEINFO shell_info; 
ZeroMemory(&shell_info, sizeof(shell_info)); 

shell_info.cbSize = sizeof(SHELLEXECUTEINFO); 
shell_info.fMask = SEE_MASK_ASYNCOK | SEE_MASK_NO_CONSOLE; 
shell_info.hwnd = NULL; 
shell_info.lpVerb = NULL; 
shell_info.lpFile = L"C:/ATDK/Executor"; 
shell_info.lpParameters = (LPCWSTR)wss.str().c_str(); 
shell_info.lpDirectory = NULL; 
shell_info.nShow = SW_MINIMIZE; 
shell_info.hInstApp = NULL; 
// 1 
ShellExecuteEx(&shell_info); 
// this sucks, 
// GetLastError returns err code 2147483658, 
//FormatMessage returns The data necessary to complete this operation is not yet available 

// 2 
ShellExecute(NULL, NULL, L"C:/ATDK/Executor", (LPCWSTR)wss.str().c_str(), NULL, NULL); 
// OK! 
+1

那(LPCWSTR)強制轉換隻會阻止編譯器告訴你代碼是錯誤的,它並沒有阻止你做錯了。如果您不想使用mbstowcs()或MultiByteToWideString()轉換爲Unicode字符串,則使用SHELLEXECUTEINFOA和ShellExecuteExA()。 –

+0

你也沒有正確地檢查錯誤。你必須檢查函數的返回值。 –

+0

[將std :: string轉換爲LPCSTR時出現奇怪行爲]的可能重複(http://stackoverflow.com/questions/11370536/weird-behavior-while-converting-a-stdstring-to-a-lpcstr) –

回答

5

你的錯誤是在這裏:

shell_info.lpParameters = (LPCWSTR)wss.str().c_str(); 

wss.str()返回一個臨時對象,在創建它充分表達結束後不再存在。在此之後使用它是未定義的行爲

要解決這個問題,您必須構造一個std::wstring對象,該對象的壽命足夠長,以致能夠返回ShellExecuteEx

std::wstringstream wss; 
wss << L"-unused" << " " 
    << L"parameter" << " " 
    // ... 

SHELLEXECUTEINFO shell_info; 
ZeroMemory(&shell_info, sizeof(shell_info)); 

// Construct string object from string stream 
std::wstring params{ wss.str() }; 

shell_info.cbSize = sizeof(SHELLEXECUTEINFO); 
shell_info.fMask = SEE_MASK_ASYNCOK | SEE_MASK_NO_CONSOLE; 
shell_info.hwnd = NULL; 
shell_info.lpVerb = NULL; 
shell_info.lpFile = L"C:\\ATDK\\Executor"; // Path separator on Windows is \ 
shell_info.lpParameters = params.c_str(); // Use string object that survives the call 
shell_info.lpDirectory = NULL; 
shell_info.nShow = SW_MINIMIZE; 
shell_info.hInstApp = NULL; 

ShellExecuteEx(&shell_info); 

請注意,您的第二個呼叫

ShellExecute(NULL, NULL, L"C:\\ATDK\\Executor", wss.str().c_str(), NULL, NULL); 

可靠地工作。即使wss.str()仍然返回一個臨時值,它仍然有效直到完整表達式結束(即在整個函數調用期間)。