ShellExecuteEx不传递长命令

ban*_*a36 0 c++ windows winapi

当我使用带有这样一个命令的ShellExecuteEx时,"-unused parameter -action capturescreenshot -filename C:\\ATDK\\Screenshots\\abcd.jbg"一切正常,Executor.exe以char* argv[]所有大约开始.9个参数.但是当命令有更多符号时,例如文件名是"abc ... xyz.jpg",那么该进程有argc == 1且命令为空.所以在发送到ShellExecute之前命令没问题我将其更改为ShellExecute,而不是Ex,它可以工作!命令可能很长,并且成功通过.任何人都能解释一下有什么区别吗?这是我填写SHELLEXECUTEINFO的代码.

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!
Run Code Online (Sandbox Code Playgroud)

IIn*_*ble 5

你的错误在这里:

shell_info.lpParameters = (LPCWSTR)wss.str().c_str();
Run Code Online (Sandbox Code Playgroud)

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); 
Run Code Online (Sandbox Code Playgroud)

请注意你的第二个电话

ShellExecute(NULL, NULL, L"C:\\ATDK\\Executor", wss.str().c_str(), NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

可靠地工作.尽管wss.str()仍然返回临时值,但它在完整表达式结束之前有效(即在整个函数调用期间).