2011-10-02 14 views
5

comparar los tres guiones a continuación:Cómo devolver un valor bastante cero con la propiedad de recuento de Get-Process?

Muestra 1

$a = GPS | Where {$_.ProcessName -Match 'AcroRd32'} 
$a 
$a.Count 

If ($a.Count -Eq 0) 
{ 
    Echo "Adobe Reader is Off" 
} 
Else 
{ 
    Echo "Adobe Reader is On" 
} 

# If Adobe Reader is not running, how come 0 (zero) is not returned? 
# This is prettier, should I use it? Or does it slow down performance? 



Muestra 2

$a = GPS AcroRd32 
$a 
$a.Count 

If ($a.Count -Eq 0) 
{ 
    Echo "Adobe Reader is Off" 
} 
Else 
{ 
    Echo "Adobe Reader is On" 
} 

# If Adobe Reader is not running, how come 0 (zero) is not returned? 
# This is uglier, but it doesn't have to pipe any output, so does it have any performance gains? 



Muestra 3

GPS AcroRd32 | Measure | Select -Expand Count 

# 0 (zero) is returned, but with an ugly Error 



supongo parte de mi problema es que yo estoy tratando de PowerShell como si fuera VBS; Escribir el código de esta manera/estilo generalmente me daría un valor entero de cero y no lanzaría ningún error (si Adobe Reader estaba apagado, por supuesto). ¿Cuál es la forma correcta de de PowerShell para verificar que una instancia de un programa no se esté ejecutando? Las preguntas de rendimiento en los comentarios son secundarias a la pregunta "PowerShell Way".

P.S. Para ser sincero, el mensaje de error devuelto por la 3ª muestra no rompería nada, es feo, por lo que no está más allá del uso práctico, así que supongo que el verdadero problema es que soy simplemente un imbécil para la estética =^D

Respuesta

8

Este es un problema común de PowerShell.Un comando puede devolver:

  • Nada ~ nulo (no tiene la propiedad Count, conseguir que sea obtiene nulo o falla)
  • Un solo objeto (que puede tener su propia propiedad propiedad Count, el caso más confuso - puede devolver cualquier cosa, o puede no tenerlo, luego obtener Count obtiene nulo o falla)
  • 2+ matriz de objetos que tiene la propiedad Count.

La solución es simple. Cuando realmente necesite el recuento de objetos devueltos, use el operador @(). El resultado es siempre una matriz que tiene la propiedad Count.

# this is always an array 
$result = @(<command returning something or nothing>) 

# this is always a number: 
$result.Count 
+0

El '@()' operador en combinación con marcas asignación de variables iniciales de la primera muestra es bonito y funcional - '$ a = @ (GPS | Donde {$ _. ProcessName -Match 'AcroRd32'})'. En aras de satisfacer un impulso pedante, debo preguntar, ¿el esfuerzo por la estética (tubería de 'GPS' a' Donde') causa una degradación del rendimiento en comparación con solo hacer '$ a = @ (GPS AcroRd32)'? Si lo hiciera, me doy cuenta de que sería minúsculo y pasaríamos desapercibidos para nosotros, pero aún quiero saberlo para poder ser un poco menos ignorante. XD – Stisfa

+1

Medí esto para un proceso "lejano": '@ (Get-Process far) '~ 1.6 mseg. '@ (Get-Process | donde {$ _. ProcessName -eq 'far'})' ~ 6.8 msec. Desde mi experiencia 'Where-Object' y' ForEach-Object' son básicamente muy lentos, los evito en los scripts (en V2.0 esto siempre es posible). Pero todavía son útiles en la línea de comandos para tipear. –

+2

BTW, si va con '@ (GPS AcroRd32)', prepárese para errores cuando el proceso no exista. Con errores, será lento o puede fallar si la preferencia de error es * Stop *. Para evitar errores, puede utilizar este truco: http://stackoverflow.com/questions/4362275/powershell-check-if-item-exists-without-an-error-if-it-doesnt/4364807#4364807. Entonces '@ (GPS [A] croRd32)' debería ser el mejor para el rendimiento. –

2

yo sugeriría que haga algo como esto:

$count = @(get-process | ?{$_.ProcessName -eq "AcroRd32"}).count 

if($count -eq 0){ 

write-host "Adobe Reader is Off" 

} else{ 

write-host "Adobe Reader is On" 

} 

lo que el anterior es que obliga a los objetos devueltos en una matriz, por lo que si no hay procesos lector corriente, obtendrá una matriz vacía y por lo tanto, su recuento será cero. Y cuando tiene procesos, los tiene en la matriz, y obtiene el recuento distinto de cero y el código anterior funcionará como se esperaba.

alternativo basado en Sample2/Sample3:

$acrobat = gps AcroRd32 -ErrorAction SilentlyContinue 
if($acrobat){ 

    write-host "Adobe Reader is On" 

} else{ 

    write-host "Adobe Reader is Off" 

} 

En lo anterior, se suprime el error si el lector no está en funcionamiento. Entonces, si $ acrobat está configurado, usted sabe que el lector se está ejecutando.

Observaciones sobre su código:

Cuando el lector no se está ejecutando, se le asigna un $ nada y por lo tanto $a.Count -eq 0 será falsa. Cuando el lector se está ejecutando, se asigna $ a esos objetos de proceso y se obtiene $ a.Count como 1 o más y, por lo tanto, nuevamente es falso. Entonces siempre obtendrá que el lector está encendido.

1

que mencionar el error en el tercer ejemplo - puede ocultar el mensaje mediante el SilentlyContinue ErrorAction:

GPS -ea silentlycontinue AcroRd32 | Measure | Select -Expand Count 
Cuestiones relacionadas