ShellExecuteEx不通过长命令
问题描述:
当我使用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!
答
你的错误是在这里:
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()
仍然返回一个临时值,它仍然有效直到完整表达式结束(即在整个函数调用期间)。
那(LPCWSTR)强制转换只会阻止编译器告诉你代码是错误的,它并没有阻止你做错了。如果您不想使用mbstowcs()或MultiByteToWideString()转换为Unicode字符串,则使用SHELLEXECUTEINFOA和ShellExecuteExA()。 –
你也没有正确地检查错误。你必须检查函数的返回值。 –
[将std :: string转换为LPCSTR时出现奇怪行为]的可能重复(http://*.com/questions/11370536/weird-behavior-while-converting-a-stdstring-to-a-lpcstr) –