将多个 cmd.exe parameters/arguments 传递给 ShellExecute(Ex)?
Passing multiple cmd.exe parameters/arguments to ShellExecute(Ex)?
我一直在尝试使用 ShellExecute
和 ShellExecuteEx
执行 cmd.exe /c /v:on
。不过这两种方法好像都只接受一个参数,因为遇到/v:on
,Windows下显示一个The filename, directory name, or volume label syntax is incorrect.
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=Whosebug & 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
window 并输入完整的命令行:
cmd /c /v:on SET example=Whosebug & ECHO '!example! & pause'`
您得到完全相同的错误,并且更多:
cmd /c /v:on SET example=Whosebug & 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
)的文档中说明了这一点:
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line
因此,/v:on
被解释为新命令行的第一个参数,因此它被视为一个显然不存在的文件名。
交换 /V
和 /C
参数,第一个错误消失:
cmd /v:on /c SET example=Whosebug & ECHO '!example! & pause'
'!example!
'pause'' is not recognized as an internal or external command, operable program or batch file.
现在,您会注意到 !example!
没有按预期展开。那是因为您没有引用命令行,如 /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. Any other switches are ignored.
因此,将命令行用引号引起来,然后 !example!
得到扩展:
cmd /v:on /c "SET example=Whosebug & ECHO '!example! & pause'"
'Whosebug
'pause'' is not recognized as an internal or external command, operable program or batch file.
最后,pause
没有被正确解释,因为您将它放在 ECHO
的单引号内,而不是作为单独的命令放在外面:
cmd /v:on /c "SET example=Whosebug & ECHO '!example!' & pause"
'Whosebug '
Press any key to continue . . .
然后您可以从 ECHO
:
中删除单引号
C:\Users\Ryan>cmd /v:on /c "SET example=Whosebug & ECHO !example! & pause"
Whosebug
Press any key to continue . . .
我一直在尝试使用 ShellExecute
和 ShellExecuteEx
执行 cmd.exe /c /v:on
。不过这两种方法好像都只接受一个参数,因为遇到/v:on
,Windows下显示一个The filename, directory name, or volume label syntax is incorrect.
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=Whosebug & 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
window 并输入完整的命令行:
cmd /c /v:on SET example=Whosebug & ECHO '!example! & pause'`
您得到完全相同的错误,并且更多:
cmd /c /v:on SET example=Whosebug & 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
)的文档中说明了这一点:
If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line
因此,/v:on
被解释为新命令行的第一个参数,因此它被视为一个显然不存在的文件名。
交换 /V
和 /C
参数,第一个错误消失:
cmd /v:on /c SET example=Whosebug & ECHO '!example! & pause' '!example! 'pause'' is not recognized as an internal or external command, operable program or batch file.
现在,您会注意到 !example!
没有按预期展开。那是因为您没有引用命令行,如 /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. Any other switches are ignored.
因此,将命令行用引号引起来,然后 !example!
得到扩展:
cmd /v:on /c "SET example=Whosebug & ECHO '!example! & pause'" 'Whosebug 'pause'' is not recognized as an internal or external command, operable program or batch file.
最后,pause
没有被正确解释,因为您将它放在 ECHO
的单引号内,而不是作为单独的命令放在外面:
cmd /v:on /c "SET example=Whosebug & ECHO '!example!' & pause" 'Whosebug ' Press any key to continue . . .
然后您可以从 ECHO
:
C:\Users\Ryan>cmd /v:on /c "SET example=Whosebug & ECHO !example! & pause" Whosebug Press any key to continue . . .