简体   繁体   English

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

[英]Passing multiple cmd.exe parameters/arguments to ShellExecute(Ex)?

I've been trying to get cmd.exe /c /v:on executed using ShellExecute and ShellExecuteEx . 我一直在尝试使用ShellExecuteShellExecuteEx使cmd.exe /c /v:on执行。 However, both methods only seem to accept one parameter, because when it encounters the /v:on , a The filename, directory name, or volume label syntax is incorrect. 但是,这两种方法似乎都只接受一个参数,因为当遇到/v:onThe filename, directory name, or volume label syntax is incorrect. is shown under Windows 7. 在Windows 7下显示。

This is the code i've tried and am currently messing with (without luck): 这是我尝试过的代码,目前正在搞乱(没有运气):

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

}

Since cmd.exe is an executable file, you should be using CreateProcess() instead of ShellExecuteEx() (which is just going to call CreateProcess() internally anyway, so get rid of the middle man). 由于cmd.exe是可执行文件,因此您应该使用CreateProcess()而不是ShellExecuteEx() (无论如何,这将只是在内部调用CreateProcess() ,因此请除掉中间人)。

In any case, this is not a ShellExecute() problem. 无论如何,这不是ShellExecute()问题。 If you open a cmd.exe window and enter your complete command line: 如果您打开cmd.exe窗口并输入完整的命令行:

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

You get the exact same error, and more: 您会得到完全相同的错误,甚至更多:

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.

The reason for the first error is because /v is a parameter of cmd.exe itself, not a separate command that /C can execute. 第一个错误的原因是因为/vcmd.exe本身的参数,而不是/C可以执行的单独命令。 Everything that follows /C (or /K ) is a new command line, so it must be the last parameter specified when calling cmd.exe . /C (或/K )后面的所有内容都是新的命令行,因此它必须是调用cmd.exe时指定的最后一个参数。 This is stated in the documentation for /C (and /K ): /C (和/K )的文档中对此进行了说明:

If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line 如果指定了/ C或/ K,则将开关后的其余命令行作为命令行处理

As such, /v:on is being interpreted as the first parameter of a new command line, and so it gets treated as a filename which obviously doesn't exist. 因此, /v:on被解释为新命令行的第一个参数,因此将其视为显然不存在的文件名。

Swap the /V and /C parameters, and the first error goes away: 交换/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.

Now, you will notice that !example! 现在,您会注意到!example! is not being expanded as expected. 没有按预期扩展。 That is because you are not quoting the command-line, as the documentation for /C (and /K ) says: 那是因为您没有引用命令行,因为/C (和/K )的文档中说:

Note that multiple commands separated by the command separator '&&' are accepted for string if surrounded by quotes . 请注意, 如果用引号引起来,则接受由命令分隔符“ &&”分隔的多个命令。 Also, for compatibility reasons, /X is the same as /E:ON, /Y is the same as /E:OFF and /R is the same as /C. 另外,出于兼容性原因,/ X与/ E:ON相同,/ Y与/ E:OFF相同,/ R与/ C相同。 Any other switches are ignored. 任何其他开关都将被忽略。

So, wrap the command-line in quotes, and then !example! 因此,将命令行用引号引起来,然后加!example! gets expanded: 得到扩展:

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.

And lastly, pause is not being interpreted correctly because you put it inside of the single quotes of the ECHO instead of outside as a separate command: 最后, pause没有正确解释,因为您将其放在ECHO的单引号内,而不是将其作为单独的命令放在外部:

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

'stackoverflow '
Press any key to continue . . .

And then you can drop the single quotes from ECHO : 然后您可以从ECHO删除单引号:

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

stackoverflow
Press any key to continue . . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM