将多个cmd.exe参数/参数传递给ShellExecute(Ex)?

时间:2017-10-02 22:03:15

标签: c++ cmd parameters shellexecute shellexecuteex

我一直在尝试使用cmd.exe /c /v:onShellExecute执行ShellExecuteEx。但是,这两种方法似乎只接受一个参数,因为当它遇到/v:on时,Windows 7下会显示The filename, directory name, or volume label syntax is incorrect.

这是我尝试过的代码,目前正在搞乱(没有运气):

#include <windows.h>

int main()

{

    SHELLEXECUTEINFO info = {0};

    info.cbSize = sizeof(SHELLEXECUTEINFO);
    info.fMask = SEE_MASK_NOCLOSEPROCESS;
    info.hwnd = NULL;
    info.lpVerb = NULL;
    info.lpFile = "cmd.exe";
    info.lpParameters = "/c /v:on SET example=stackoverflow & ECHO '!example! & pause'";
    info.lpDirectory = NULL;
    info.nShow = SW_SHOW;
    info.hInstApp = NULL;

    ShellExecuteEx(&info);

//  wait for process to terminate
//  WaitForSingleObject(info.hProcess, INFINITE);

    return 0;

}

1 个答案:

答案 0 :(得分:2)

由于cmd.exe是一个可执行文件,因此您应该使用CreateProcess()而不是ShellExecuteEx()(无论如何都会在内部调用CreateProcess(),因此请删除中间人)。

无论如何,这不是ShellExecute()问题。如果您打开cmd.exe窗口并输入完整的命令行:

cmd /c /v:on SET example=stackoverflow & ECHO '!example! & pause'`

你得到完全相同的错误,以及更多:

cmd /c /v:on SET example=stackoverflow & ECHO '!example! & pause'

The filename, directory name, or volume label syntax is incorrect.
'!example!
'pause'' is not recognized as an internal or external command, operable program or batch file.

第一个错误的原因是因为/v本身是cmd.exe的参数,而不是/C可以执行的单独命令。 /C(或/K)后面的所有内容都是新的命令行,因此它必须是调用cmd.exe时指定的最后一个参数。这在/C(和/K)的文档中说明:

  

如果指定了/ C或/ K,那么后面的命令行的其余部分   交换机作为命令行处理

因此,/v:on被解释为新命令行的第一个参数,因此它被视为显然不存在的文件名。

交换/V/C参数,第一个错误就消失了:

cmd /v:on /c SET example=stackoverflow & ECHO '!example! & pause'

'!example!
'pause'' is not recognized as an internal or external command, operable program or batch file.

现在,您会注意到!example!未按预期展开。这是因为您没有引用命令行,因为/C(和/K)的文档说:

  

请注意,多个命令由命令分隔符&amp;&amp;&amp;&#39;分隔。如果用引号包围,则接受字符串。另外,出于兼容性原因,/ X与/ E:ON相同,/ Y与/ E:OFF相同,/ R与/ C相同。任何其他开关都会被忽略。

因此,将命令行包装在引号中,然后展开!example!

cmd /v:on /c "SET example=stackoverflow & ECHO '!example! & pause'"

'stackoverflow
'pause'' is not recognized as an internal or external command, operable program or batch file.

最后,pause没有被正确解释,因为你把它放在ECHO的单引号内而不是外面作为一个单独的命令:

cmd /v:on /c "SET example=stackoverflow & ECHO '!example!' & pause"

'stackoverflow '
Press any key to continue . . .

然后你可以从ECHO中删除单引号:

C:\Users\Ryan>cmd /v:on /c "SET example=stackoverflow & ECHO !example! & pause"

stackoverflow
Press any key to continue . . .