Вы писали:
$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