Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ShellExecuteEx不';不要传长指令_C++_Windows_Winapi - Fatal编程技术网

C++ ShellExecuteEx不';不要传长指令

C++ ShellExecuteEx不';不要传长指令,c++,windows,winapi,C++,Windows,Winapi,当我将ShellExecuteEx与这样一个命令一起使用时,“-未使用的参数-action capture屏幕截图-filename C:\\ATDK\\Screenshots\\abcd.jbg”一切正常,Executor.exe以char*argv[]开头,包含所有大约9个参数。但是,如果该命令包含多个符号,例如文件名为“abc…xyz.jpg”,则该进程的argc==1,并且该命令为空。因此,在我将命令更改为ShellExecute(而不是Ex)之后,在发送到ShellExecute之前,

当我将ShellExecuteEx与这样一个命令一起使用时,
“-未使用的参数-action capture屏幕截图-filename C:\\ATDK\\Screenshots\\abcd.jbg”
一切正常,Executor.exe以
char*argv[]
开头,包含所有大约9个参数。但是,如果该命令包含多个符号,例如文件名为“abc…xyz.jpg”,则该进程的argc==1,并且该命令为空。因此,在我将命令更改为ShellExecute(而不是Ex)之后,在发送到ShellExecute之前,该命令是正确的,它可以工作!命令可能很长,并且已成功传递。有人能解释一下有什么区别吗?这是我填写的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!
std::wstringstream wss;
wss您的错误在这里:

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); 
工作可靠。即使
wss.str()
仍然返回一个临时值,但它在完整表达式结束之前(即在整个函数调用过程中)是有效的。

您的错误在这里:

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); 

工作可靠。即使
wss.str()
仍然返回一个临时值,它在完整表达式结束之前(即在整个函数调用过程中)是有效的。

该(LPCWSTR)强制转换只会阻止编译器告诉您代码错误,但不会阻止您出错。如果不想使用mbstowcs()或MultiByteToWideString()转换为Unicode字符串,请使用ShellExecuteInfo和ShellExecuteExA()。您也没有正确检查错误。您必须检查函数的返回值。@HansPassant的可能重复:强制转换总是可疑的,但是在这种情况下它是不必要的。如果您最初的分析是正确的,将
ShellExecuteEx
更改为
ShellExecute
将不会修复它。该(LPCWSTR)强制转换只会阻止编译器告诉您代码错误,但不会阻止您出错。如果不想使用mbstowcs()或MultiByteToWideString()转换为Unicode字符串,请使用ShellExecuteInfo和ShellExecuteExA()。您也没有正确检查错误。您必须检查函数的返回值。@HansPassant的可能重复:强制转换总是可疑的,但是在这种情况下它是不必要的。如果您最初的分析是正确的,将
ShellExecuteEx
更改为
ShellExecute
将无法修复它。