我最近一直在努力使一组指令能够作为单行代码发挥作用。我想要实现的是以提升的权限运行特殊的 CMD 指令,但从非特权的 CMD 开始。我发现我想要做的事情可以通过利用 PowerShell 作为中间人来实现,并且我成功地创建了一些行之有效的俏皮话,但我无法理解更复杂的场景。这是我计划使用的程序流程:
CMD(非特权)-> PowerShell(非特权,触发管理员权限)-> CMD 或 PowerShell(现在具有管理员权限)-> 执行所需的指令(需要管理员权限)
我必须从非特权 CMD 开始。我计划从那里启动 PS session ,因为我发现了一个很好的“技巧”(即,在命令末尾使用 -Verb RunAs
),它可以让我切换到管理 CMD/PS session 只需在 Windows UAC GUI 中按"is"即可。
这是我必须在管理 CMD/PS session 中运行的最终命令:
tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt"
此外,该命令还必须从特定文件夹执行。 我可以确认,这个命令本身可以正常工作。
我已经一步步进行,我可以保证下一个命令在从 PS 启动时有效:
cmd \"/k cd C:\MY\PATH\WITHOUT\SPACES && tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt"\"
因此,我尝试实现完整的解决方案,从非特权 CMD 启动它:
powershell.exe -Command Start-Process cmd \"/k cd C:\MY\PATH\WITHOUT\SPACES && tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt" && exit\" -Verb RunAs
但这失败了,因为 tbcon
没有正确接收参数,并且确实报告了我:
[tbcon] ERROR - Invalid argument: '--optionsfile'.
我怀疑这是因为 CMD 弄乱了 a2lmerger
和 --opstionsfile
之间的空格(最终是 --optionsfile
之间的空格)和 _gen[...]
),但我花了很多时间试图解决这个问题,但运气不佳。
此外,如果能够将 C:\MY\PATH\WITHOUT\SPACES
替换为也包含空格的路径,那就太好了,但这将是一个额外的好处。
感谢大家的帮助!
最佳答案
任何 "
字符。您需要将其保留为传递给 Windows PowerShell 的命令的一部分 CLI的-Command
参数必须转义为 \"
(否则,初始命令行解析将删除它们)。
虽然您已经为嵌套
cmd
执行此操作命令行总体,嵌入式"
-run:
周围的字符选项值缺乏这种转义。将它们转义为
\"
然而,这还不够,因为它们需要被解释为"
在 PowerShell 字符串文字中,其中"
必须转义为`"
。因此,您必须以正确的顺序组合这些转义机制,即:`\"
- 这同样适用于括起
cd
"..."
中的参数
- 这同样适用于括起
因此:
powershell.exe -Command Start-Process cmd \"/k cd `\"C:\MY\PATH\WITH SOME\SPACES`\" && tbcon -run:`\"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt`\" && exit\" -Verb RunAs
注意边缘情况:
<强> cmd.exe
本身没有转义的概念"
字符。;也就是说,甚至是"
在\"
被视为开始或结束双引号字符串,嵌套 \"...\"
因此创建 cmd.exe
的子字符串考虑未加引号,导致诸如 &
之类的字符被解释为 cmd.exe
元字符,放在前面,可以破坏命令。
此陷阱适用于从 cmd.exe
运行的任何命令。 ,不仅仅是在调用PowerShell时;这是 cmd.exe
-仅示例:
:: From cmd.exe.
:: BREAKS, because the 2nd & is considered UNQUOTED causing
:: interpretation as the statement-sequencing operator.
:: Prints "A & \"B, then looks for a command named C\" D"
echo "A & \"B & C\" D"
解决方法:
手动、视情况解决方法:选择性
^
-转义这样的字符,但是需要具体了解哪些子字符串cmd.exe
考虑未加引号,这是麻烦且不平凡的。:: From cmd.exe. :: OK, due to ^-escaping of the 2nd & :: Prints "A & \"B & C\" D" echo "A & \"B ^& C\" D"
有条理的解决方法:
如果 objective-c LI 支持,请使用
""
代替\"
作为 Fugitive"
里面"..."
字符串,这从根本上避免了问题(cmd.exe
,它也不将""
识别为特殊的,然后实际上看到"..."
字符串的串联,因此一切在其中引用)。
使用 Microsoft 编译器创建的 CLI 通常确实接受""
(可与\"
互换),其中包括pwsh.exe
,PowerShell(核心)7+ CLI,但不幸的是 - 不是powershell.exe
、Windows PowerShell CLI(请参阅下一点)。
调用pwsh.exe
时,附上-Command
"..."
中的参数总体而言,并使用""
用于嵌入式"
::: From cmd.exe. :: OK, due to "..." enclosure and :: escaping of embedded " as "" (if you tried to use \", this would break) :: Prints "A & B" pwsh.exe -Command " Write-Output ""A & B"" "
对于
powershell.exe
,Windows PowerShell CLI,不幸的是,解决方法比较麻烦; 使用"^""
(原文如此)在-Command
内"..."
中包含的参数总体::: From cmd.exe. :: OK, due to overall "..." enclosure and :: escaping of embedded " as "^"" (sic) :: Prints "A & B" powershell.exe -Command " Write-Output "^""A & B"^"" "
- 不幸的是,这种技术在
for /f
内部不起作用循环,需要更复杂的解决方法,在 this answer 的底部部分讨论.
- 不幸的是,这种技术在
关于windows - 通过 CMD 和 PowerShell 终端提示符链执行复杂指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76289281/