ShellExecute:动词"runas";不适用于路径中带有空格的批处理文件
我正在使用ShellExecuteW启动批处理文件.代码看起来像这样:
I am using ShellExecuteW to start a batch file. Code looks somewhat like this:
ShellExecuteW(GetDesktopWindow(), wide_verb.c_str(), wide_filename.c_str(), wide_parameters.c_str(), NULL, SW_SHOW);
其中wide_
变量的类型为wstring
.该代码适用于文件路径和动词的任意组合,但动词"runas"(获得管理员权限)和给定路径wide_filename
中带有空格的批处理文件除外. UAC提示符将弹出,确认后不久,命令提示符将闪烁,提示找不到该路径,该路径从该路径的第一个空格处切断.
Where the wide_
variables are of type wstring
. This code works fine for arbitrary combinations of file path and verb, except for verb "runas" (to get administrator rights) and a batch file with spaces in the given path wide_filename
. The UAC prompt will pop up and, after confirmation, for a short moment the command prompt will flash up saying that the path could not be found, cutting off at the first space in the path.
我已经尝试用其他引号将文件名引起来,但这无济于事.
I already tried wrapping the file name in additional quotes, but that didn't help.
原因可能是.bat文件不是真正的可执行文件",而是文档及其相关文件
The reason is probably that .bat files aren't really "executables", but documents, and therefor
ShellExecuteW(GetDesktopWindow(), L"runas", L"C:\\Path To\\file.bat", L"Parameters For Batch", NULL, SW_SHOW);
在内部映射到提升的执行力
is internally mapped to an elevated execution of
cmd.exe /C "C:\Path To\file.bat" "Parameters for Batch"
虽然应该与
cmd.exe /S /C " "C:\Path To\file.bat" Parameters for Batch "
确实,如果我执行这样的操作:
And indeed, if I execute something like this:
ShellExecuteW(GetDesktopWindow(), L"runas", L"cmd.exe", L"/S /C \" \"C:\\Path To\\file.bat\" Parameters For Batch \"", NULL, SW_SHOW);
成功了!
但是,似乎不是最干净的方法来对可执行文件(在这种情况下为cmd.exe)进行硬编码".对于批处理文件而言,这实际上并不重要,但是对于其他带有参数的脚本类型的文档,它可能变得有意义.
However, it doesn't seem like the cleanest approach to "hardcode" the executable (cmd.exe in this case) like that. For batch files it really doesn't matter, but for other script-type documents that take parameters it might become relevant.
所以问题是:是否可以执行通过ShellExecute或类似机制提升的批处理文件(路径中带有空格),而无需将其显式传递给cmd.exe?
So the question is: Is it possible to execute a batch file (with spaces in its path) elevated via ShellExecute or a similar mechanism, without explicitly passing it to cmd.exe?
CreateProcessWithLogonW is what you need here. It has a lot of arguments, but at the end of the page you'll see an Examples section instructing how to initialize the args.
As for hardcoding cmd.exe
here's what CreateProcess official doc says (at the end of the section describing the lpApplicationName
argument):
要运行批处理文件,必须启动命令解释器.将lpApplicationName设置为cmd.exe,并将lpCommandLine设置为以下参数:/c加上批处理文件的名称.
To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.
所以我认为你很好.当然,包含在"
中的路径仍然适用.
So i think you're good. Of course the path enclosing in "
s still applies.