2010-01-26 10 views
14

Estoy tratando de ejecutar un exe externo de un script de powershell.powershell enviando parámetros múltiples a un comando externo

Este exe quiere 4 parámetros.

He estado intentando cada combo de invocar-elemento, invoke-command, & 'C: \ Archivos de programa \ mycmd.exe myparam', hice un atajo en C: \ para deshacerse de los espacios en la ruta.

Puedo hacerlo funcionar con un parámetro, pero no con más. Tengo varios errores

En resumen, ¿cómo se envían 4 parámetros a un exe?

Respuesta

20

Lo mejor es que se muestre a mano. Una vez que ve lo que está pasando, puede acortarlo simplemente usando comas entre cada argumento.

$arg1 = "filename1" 
$arg2 = "-someswitch" 
$arg3 = "C:\documents and settings\user\desktop\some other file.txt" 
$arg4 = "-yetanotherswitch" 

$allArgs = @($arg1, $arg2, $arg3, $arg4) 

& "C:\Program Files\someapp\somecmd.exe" $allArgs 

... abreviada:

& "C:\Program Files\someapp\somecmd.exe" "filename1", "-someswitch", "C:\documents and settings\user\desktop\some other file.txt", "-yetanotherswitch" 
+3

Ten cuidado con '& 'C: \ archivos de programa \ someapp \ somecmd.exe" -arg $ allArgs' - el '-arg' no es necesario a menos que tengas la intención de pasar' -arg' como parámetro a algunoscmd .exe. –

+0

Sí, por la razón que sea que me he referido a esto hoy, ¡y noté que la línea de código con el -arg no funcionaba! Oops/eliminado. –

12

En el caso fácil, pasar argumentos a un exe nativo es tan simple como usar un comando integrado:

PS> ipconfig /allcompartments /all 

Puede se encuentra con problemas cuando especifica una ruta completa a un EXE y esa ruta contiene espacios. Por ejemplo, si ve esto PowerShell:

PS> C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\sn.exe -k .\pubpriv.snk 

interpreta el comando a ser "C: \ Program" y "Files \ Microsoft" como primer parámetro, "SDKs \ Windows \ v7.0 \ Bin \ sn. exe" como el segundo parámetro, etc. la solución simple es poner la ruta en una cadena de usar el operador de invocación & para invocar el comando llamado por el camino por ejemplo:

PS> & 'C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\sn.exe' -k .\pubpriv.snk 

la siguiente área nos encontramos con problemas con es cuando los argumentos son complejos y/o usan caracteres que PowerShell interpreta especialmente ej .:

PS> sqlcmd -v user="John Doe" -Q "select '$(user)' as UserName" 

Esto no funciona y podemos depurar esto utilizando una herramienta del PowerShell Community Extensions llamada echoargs.exe que muestra exactamente cómo el EXE nativo recibe los argumentos de PowerShell.

PS> echoargs -v user="John Doe" -Q "select '$(user)' as UserName" 
The term 'user' is not recognized as the name of a cmdlet, function, 
script file, or operable program. Check the spelling of the name, ... 
<snip> 

Arg 0 is <-v> 
Arg 1 is <user=John Doe> 
Arg 2 is <-Q> 
Arg 3 is <select '' as UserName> 

Tenga en cuenta que con Arg3 $(user) se interpreta & evaluado por PowerShell y da como resultado una cadena vacía. Puede solucionar este problema y un buen número de problemas similares mediante el uso de comillas simples en lugar de qoutes dobles a menos que realmente necesita PowerShell para evaluar un ejemplo de variable:

PS> echoargs -v user="John Doe" -Q 'select "$(user)" as UserName' 
Arg 0 is <-v> 
Arg 1 is <user=John Doe> 
Arg 2 is <-Q> 
Arg 3 is <select $(user) as UserName> 

Si todo lo demás falla, utilizar una cuerda y aquí Inicio- proceso de esta manera:

PS> Start-Process echoargs -Arg @' 
>> -v user="John Doe" -Q "select '$(user)' as UserName" 
>> '@ -Wait -NoNewWindow 
>> 
Arg 0 is <-v> 
Arg 1 is <user=John Doe> 
Arg 2 is <-Q> 
Arg 3 is <select '$(user)' as UserName> 

Nota si está utilizando PSCX 1.2 tendrá que anteponer Puesta en proceso como tal - Microsoft.PowerShell.Management\Start-Process utilizar una función de puesta en proceso de cmdlet de PowerShell.

+0

Hm; Al ver esto, me pregunto de nuevo: ¿existe una buena razón para mantener las versiones PSCX de los cmdlets que incluye PowerShell v2? Get-Random me hizo tropezar varias veces debido a su semántica completamente diferente. – Joey

+0

No, no hay. Así que hemos movido los tres cmdlets que tienen colisiones de nombres a un módulo separado en PSCX 2.0 (Pscx.Deprecated.psd1). Hay una versión beta 2.0 disponible para descargar, pero debido a que está basada en módulos, solo funciona en PowerShell 2.0. –

+2

Acabo de notar esto: [PowerShell y comandos externos hechos a la derecha] (http://edgylogic.com/blog/powershell-and-external-commands-done-right/). Consejo casi idéntico. –

Cuestiones relacionadas