2012-01-04 27 views
7

Estoy intentando ejecutar un trabajo en segundo plano que es un .exe con parámetros y el destino tiene espacios. Por ejemplo:Trabajo en segundo plano en Powershell

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

y quiero ejecutar esto con parámetros:

foo.exe /param1 /param2, etc. 

sé que Start-Job hace esto, pero yo he probado toneladas de diferentes combinaciones y tampoco me da un error debido el espacio en blanco o debido a los parámetros. ¿Puede alguien ayudarme con la sintaxis aquí? Necesito suponer que $exec es la ruta del ejecutable porque es parte de un archivo de configuración y podría cambiar más adelante.

Respuesta

8

Una forma de hacerlo es usar un script block con un bloque de parámetros.

Si hay un solo argumento con un espacio en él, como una ruta de archivo/carpeta, debe citarse para tratarlo como un único elemento. Los argumentos son una matriz pasada al bloque de script.

En este ejemplo se utiliza un bloque de script pero también se puede utilizar un script de PowerShell utilizando el parámetro -FilePath del cmdlet Start-Job en lugar del parámetro -ScriptBlock.

Aquí es otro ejemplo que tiene argumentos con espacios:

$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 

Aquí hay un ejemplo usando el $args variable incorporada en lugar del bloque 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

Gracias por la ayuda! ¿Qué significa 2> y 1? – Brian

+0

@Brian Ah sí que redirigirá la secuencia de error estándar (2) a la salida estándar (1). Esto garantiza que recibirá todo el texto del ejecutable desde el cmdlet 'Receive-Job'.Normalmente, lo que hago en el trabajo de fondo es capturar el resultado de un ejecutable '$ out = xcopy $ a $ b 2> & 1' luego verificar si el código de salida (' $ LASTEXITCODE') es distinto de cero y si es así tirar el capturado texto como mensaje de excepción: 'throw $ out'. –

3

El truco de Andy generalmente funciona muy bien. Si tiene conjuntos de parámetros, o de otra manera desea mover información compleja en el trabajo, también puede probar esta técnica:

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

y en el trabajo ...

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

utilizo ambos enfoques de manera rutinaria .

que utilizan parámetros -ArgumentList/ScriptBlock cuando:

  • No estoy tratando con juegos de parámetros
  • estoy usando un empleo en memoria (como la capacidad -AsJob en ShowUI o PTC), donde los argumentos son objetos reales, y no pueden morir
  • estoy corriendo en un contexto de usuario en el que puedo ejecutar un trabajo, pero no se pueden almacenar en el disco (servidores web, los laboratorios que cumplen con ISO, etc.)

si necesito comp lex argumentos, y no necesitan pasarse en la memoria (o es conveniente tenerlos en el disco más tarde), voy a utilizar el enfoque hashtable.

Espero que esto ayude

Cuestiones relacionadas