2012-01-04 4 views
7

Я пытаюсь запустить задание в фоновом режиме, который является .exe с параметрами, и место назначения имеет пробелы. Например:Справочная работа в Powershell

$exec = "C:\Program Files\foo.exe" 

, и я хочу, чтобы запустить это с параметрами:

foo.exe /param1 /param2, etc. 

Я знаю, что Start-Job делает это, но я пытался тонны различных комбинаций и он либо дает мне ошибку из-за пробел или из-за параметров. Может ли кто-нибудь помочь мне с синтаксисом здесь? Мне нужно предположить, что $exec - это путь исполняемого файла, поскольку он является частью файла конфигурации и может впоследствии измениться.

ответ

8

Один из способов сделать это - использовать script block с блоком параметров.

Если есть один аргумент с пробелом в нем, например путь к файлу/папке, он должен быть процитирован, чтобы рассматривать его как отдельный элемент. Аргументы - это массив, переданный блоку сценария.

В этом примере используется блок сценария, но вы также можете использовать скрипт PowerShell, используя параметр Start-Job командлета вместо параметра -ScriptBlock-FilePath.

Вот еще один пример, который имеет аргументы с пробелами:

$scriptBlock = { 
    param (
     [string] $Source, 
     [string] $Destination 
    ) 
    $output = & xcopy $Source $Destination 2>&1 
    return $output 
} 

$job = Start-Job -scriptblock $scriptBlock -ArgumentList 'C:\My Folder', 'C:\My Folder 2' 
Wait-Job $job 
Receive-Job $job 

Вот пример с использованием $args встроенной переменной вместо param блока.

$scriptBlock = { 
    $output = & xcopy $args 2>&1 
    return $output 
} 

$path1 = "C:\My Folder" 
$path2 = "C:\My Folder 2" 

"hello world" | Out-File -FilePath "$path1\file.txt" 

$job = Start-Job -scriptblock $scriptBlock -ArgumentList $path1, $path2 
Wait-Job $job 
Receive-Job $job 
+0

Спасибо за помощь! Что означает 2> & 1? – Brian

+0

@Brian Ah да, что перенаправит стандартный поток ошибок (2) в стандартный поток (1). Это гарантирует, что вы получите весь текст из исполняемого файла из командлета «Получить-Job».Обычно то, что я делаю в фоновом задании, это захват вывода исполняемого '$ out = xcopy $ a $ b 2> & 1', а затем проверить, не является ли код выхода (' $ LASTEXITCODE') ненулевым, и если это так бросает захваченный текст как сообщение об исключении: 'throw $ out'. –

3

Трюк Энди в целом работает очень хорошо. Если у вас есть наборы параметров, или в противном случае необходимо переместить сложную информацию в работу, вы также можете попробовать эту технику:

$jobArgs = @{Source="foo"; Destination="bar"} 
$jobArgs |Export-CliXml -Path $env:\Temp\MyArgs.clixml 

и в работе ...

Start-Job { 
.... $jobArgs = Import-CliXml -Path $env:\Temp\MyArgs.clixml 
} | Wait-Job | Receive-Job 

я использую оба подхода обычно ,

Я использую параметры -ArgumentList/ScriptBlock когда:

  • Я не имею дело с наборами параметрами
  • Я использую в памяти задание (например, возможности -AsJob в ShowUI или WPK), где аргументы являются реальными объектами, и они не могут умереть
  • Я бегу в контексте пользователя, где я могу запустить работу, но не может хранить на диске (веб-серверы, совместимые лаборатории ISO, и т.д.)

Если мне нужен comp lex, и их не нужно передавать в памяти (или в противном случае удобнее их на диске позже), я буду использовать подход хеш-таблицы.

Надеюсь, что это поможет