2012-01-04 5 views
7

Sto provando a eseguire un lavoro in uno sfondo che è un exe con parametri e la destinazione ha spazi. Per esempio:Lavoro in background in PowerShell

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

e voglio eseguire questo con i parametri:

foo.exe /param1 /param2, etc. 

so che Start-Job fa questo, ma ho provato tonnellate di combinazioni diverse e neanche mi dà un errore a causa del lo spazio bianco o a causa dei parametri. Qualcuno può aiutarmi con la sintassi qui? Devo supporre che $exec sia il percorso dell'eseguibile perché fa parte di un file di configurazione e potrebbe cambiare in seguito.

risposta

8

Un modo per fare ciò è utilizzare un script block con un blocco param.

Se esiste un singolo argomento con uno spazio al suo interno, ad esempio un percorso file/cartella, è necessario quotarlo per considerarlo come un singolo elemento. Gli argomenti sono una matrice passata al blocco di script.

Questo esempio utilizza un blocco di script ma è anche possibile utilizzare uno script PowerShell utilizzando il parametro -FilePath del cmdlet Start-Job anziché il parametro -ScriptBlock.

Ecco un altro esempio che utilizza gli argomenti con spazi:

$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 

Ecco un esempio utilizzando il $args variabile integrata invece del blocco 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

Grazie per l'aiuto! Cosa significa 2> & 1? – Brian

+0

@Brian Ah sì che reindirizzerà il flusso di errore standard (2) al flusso di uscita standard (1). Ciò garantisce che riceverai tutto il testo dall'eseguibile dal cmdlet 'Receive-Job'.In genere quello che faccio nel lavoro in background è catturare l'output di un eseguibile '$ out = xcopy $ a $ b 2> & 1', quindi controlla se il codice di uscita (' $ LASTEXITCODE') è diverso da zero e in tal caso lancia il catturato testo come messaggio di eccezione: 'buttare $ out'. –

3

Il trucco di Andy generalmente funziona molto bene. Se si dispone di set di parametri, o in altro modo da spostare informazioni complesse nel lavoro, si può anche provare questa tecnica:

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

e nel lavoro ...

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

Io uso entrambi gli approcci di routine .

Io uso i parametri -ArgumentList/scriptblock quando:

  • io non sto trattando con parametro imposta
  • sto usando un lavoro in memoria (come la capacità -AsJob in ShowUI o PLC), dove gli argomenti sono oggetti reali, e non possono morire
  • sono in esecuzione in un contesto utente in cui posso eseguire un lavoro, ma non in grado di memorizzare su disco (server web, ISO laboratori conformi, ecc)

Se ho bisogno di comp argomenti lex, e non hanno bisogno di essere passati in memoria (o è altrimenti conveniente averli su disco in seguito), userò l'approccio di hashtable.

Spero che questo aiuti