你写道:
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
& $var
您已经注意到这不起作用。这是因为& 运算符的参数是一个字符串,表示要执行的命令(但不是参数)。正确的写法是:
$var = "C:\Program Files (x86)\Opera\Launcher.exe"
& $var /uninstall
如果您想从注册表(或其他地方)读取命令行字符串并按原样执行,避免Invoke-Expression 或调用cmd.exe 的一种方法是对字符串进行标记。这是一个执行此操作的函数:
function Split-String {
param(
[String] $inputString
)
[Regex]::Matches($inputString, '("[^"]+")|(\S+)') | ForEach-Object {
if ( $_.Groups[1].Success ) {
$_.Groups[1].Value
}
else {
$_.Groups[2].Value
}
}
}
返回数组中的第一个元素是可执行文件的名称,其余元素(如果有)是可执行文件的参数。数组元素周围的引号被保留。
您可以使用该函数通过& 运算符运行可执行文件,如下所示:
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
$tokens = @(Split-String $var)
$command = $tokens[0] -replace '^"?([^"]+)"?$', '$1'
if ( $tokens.Count -eq 1 ) {
& $command
}
else {
& $command $tokens[1..$($tokens.Count - 1)]
}
代码中的第三行从命令名称中删除前导和尾随 " 字符。
如果要异步运行可执行文件,可以使用Start-Process。示例:
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
$tokens = @(Split-String $var)
$startArgs = @{
"FilePath" = $tokens[0] -replace '^"?([^"]+)"?$', '$1'
}
if ( $tokens.Count -gt 1 ) {
$startArgs.ArgumentList = $tokens[1..($tokens.Count - 1)]
}
Start-Process @startArgs