执行“现实生活"Powershell中变量的命令行 [英] Execute "real life" command line from variable in Powershell
问题描述
例如,当我从注册表中读取一些卸载字符串时,例如 "C:\Program Files (x86)\Opera\Launcher.exe"/uninstall
我可以将其复制到 Powershell 命令行,以调用运算符作为前缀并执行它.
When I for example read some uninstall string from the registry like "C:\Program Files (x86)\Opera\Launcher.exe" /uninstall
I can copy it to the Powershell command line, prefix it with the call operator and execute it.
& "C:\Program Files (x86)\Opera\Launcher.exe" /uninstall
但是
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
& $var
不起作用.我当然可以说
does not work. Of course I can just say
cmd /c $var
但是如果没有额外的 cmd
进程,真的没有办法做到这一点吗?
But is there really no way to do this without an additional cmd
process?
推荐答案
为了使用 &
(如果命令名称/路径是 不带引号的文字),命令名称/路径必须与其参数分开传递.
在调用外部程序时,您可以将这些参数作为数组传递.
In order to use &
(or direct invocation if the command name/path is an unquoted literal), the command name/path must be passed separately from its arguments.
When invoking an external program, you may pass these arguments as an array.
下面的解决方案利用 PowerShell 自己的 Write-Output
cmdlet 结合安全的 Invoke-Expression
[1] 调用以便将字符串解析为其组成参数.
The solution below leverages PowerShell's own Write-Output
cmdlet in combination with a - safe - invocation of Invoke-Expression
[1]
in order to parse the string into its constituent arguments.
# Gets the arguments embedded in the specified string as an array of literal tokens
# (applies no interpolation).
# Note the assumption is that the input string contains no NUL characters
# (characters whose code point is `0x0`) - which should be a safe assumption
# Example:
# get-EmbeddedArguments '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
# yields array @( 'C:\Program Files (x86)\Opera\Launcher.exe', '/uninstall' )
function get-EmbeddedArguments ([string] $String) {
(Invoke-Expression "Write-Output -- $($String -replace '\$', "`0")") -replace "`0", '$' #"
}
# Input string.
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
# Extract the command name (program path) and arguments.
# Note the destructuring assignment that stores the return array's 1st element
# in $exe, and collects the remaining elements, if any, in $exeArgs.
$exe, $exeArgs = get-EmbeddedArguments $var
# Use & to invoke the command (name / program path) ($exe) and pass
# it all arguments as an array.
& $exe $exeArgs
<小时>
[1] 正如比尔指出的那样,Invoke-Expression
通常应该避免,因为它会带来安全风险,并且通常有更安全、更强大的选项可用.然而,这里没有简单的替代方案,通过临时替换输入字符串中的所有$
实例来避免安全风险,以防止意外的字符串插值.上>
[1] Invoke-Expression
should generally be avoided, as Bill points out, because it presents a security risk and there are typically safer and more robust options available. Here, however, there is no simple alternative, and the security risk is avoided by temporarily replacing all $
instances in the input string so as to prevent unintended string interpolation.
这篇关于执行“现实生活"Powershell中变量的命令行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!