将多个cmd.exe参数/参数传递给Shellexecute(ex)

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

本文关键字:Shellexecute ex 参数传递 cmd exe 参数      更新时间:2023-10-16

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

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

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

由于 cmd.exe是可执行文件,因此您应该使用 CreateProcess()而不是 ShellExecuteEx()(无论如何,它只是内部打电话给CreateProcess(),因此请删除中间人)。

)。

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

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

您会遇到完全相同的错误,等等:

cmd/c/v:在设置示例上= stackoverflow&echo'!示例!& 暂停'文件名,目录名称或卷标签语法不正确。'!例子!"暂停"不被认为是内部或外部命令,可操作程序或批处理文件。

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

如果指定了/c或/k,则命令行的其余部分 开关作为命令行处理

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

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

cmd/v:on/c设置示例= stackoverflow&echo'!示例!& 暂停''!例子!"暂停"不被认为是内部或外部命令,可操作程序或批处理文件。

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

请注意,多个命令由命令分隔器'&amp;&amp;'如果被引号包围,则接受字符串。同样,出于兼容的原因,/x与/e:on:on/y相同,与/e:off和/r与/c相同。任何其他开关都被忽略。

因此,将命令行包裹在引号中,然后!example!扩展:

cmd/v:on/c"设置示例= stackoverflow&echo'!示例!&暂停'"'堆栈溢出"暂停"不被认为是内部或外部命令,可操作程序或批处理文件。

最后,pause无法正确解释,因为您将其放在ECHO的单个引号中,而不是外部作为单独命令:

cmd/v:on/c"设置示例= stackoverflow&echo'!示例!'& 暂停"'堆栈溢出 '按任意键继续 。。。

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

C: users  ryan> cmd/v:on/c"设置示例= stackoverflow&echo!示例!&暂停"堆栈溢出按任意键继续 。。。