2011-07-13 15 views
7

Parece que no puedo detectar una excepción lanzada por Start-Service. Aquí está mi código:Powershell: excepción de captura lanzada cuando no se puede iniciar un servicio

try 
{ 
    start-service "SomeUnStartableService" 
} 
catch [Microsoft.PowerShell.Commands.ServiceCommandException] 
{ 
    write-host "got here" 
} 

Cuando ejecuto esto, se produce la excepción, pero no parados:

*Service 'SomeUnStartableService' start failed. 
At line:3 char:18 
+  start-service <<<< "SomeUnStartableService" 
    + CategoryInfo   : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException 
    + FullyQualifiedErrorId : StartServiceFailed,Microsoft.PowerShell.Commands.StartServiceCommand* 

$ErrorActionPreference se ajusta en Parada, por lo que este no debe ser el problema.

Cuando modifico mi código a catch [Exception], se captura la excepción y se imprime "get here".

¿start-service arroja un ServiceCommandException o algo más? ¡Parece que sí lo es pero no puedo atraparlo!

--- --- Editar

Lo ideal sería que podría escribir lo siguiente, y lanzar una excepción si start-service no lanzó una excepción, y sólo capturar una excepción lanzada por start-service:

try 
{ 
    start-service "SomeUnStartableService" 
    throw (new-object Exception("service started when expected not to start")) 
} 
catch [Microsoft.PowerShell.Commands.ServiceCommandException] 
{ 
    write-host "got here" 
} 

Respuesta

1

lo general don no limite el catch-phra se, sino manejar las excepciones con pruebas lógicas dentro del bloque catch:

try 
{ 
    start-service "SomeUnStartableService" -ea Stop 
} 
catch 
{ 
    if ($error[0].Exception -match "Microsoft.PowerShell.Commands.ServiceCommandException") 
    { 
     #do this 
    } 
    else 
    { 
     #do that 
    } 
} 

Tal vez no tan limpio, y puede resultar en grandes bloques catch. Pero si funciona ...;)

+0

Es una pena que no sea tan limpio como capturar la excepción específica, pero supongo que si eso no se puede hacer, esta es la mejor opción. – Jack

10

Try/Catch solo funciona en los errores de terminación. Utilice el parámetro ErrorAction con un valor de parada a que el error de un error de terminación y luego podrás cogerlo:

try 
{ 
    start-service "SomeUnStartableService" -ErrorAction Stop 
} 
catch 
{ 
    write-host "got here" 
} 

ACTUALIZACIÓN:

Al configurar $ ErrorActionPreference a 'stop' (o use -ErrorAction Stop) el tipo de error que obtiene es ActionPreferenceStopException, por lo que puede usarlo para detectar el error.

$ErrorActionPreference='stop' 

try 
{ 
    start-service SomeUnStartableService 
} 
catch [System.Management.Automation.ActionPreferenceStopException] 
{ 
    write-host "got here" 
} 

}

+0

si $ ErrorActionPreference está establecido en Stop no es suficiente? – JPBlanc

+0

Como $ ErrorActionPreference se establece en 'Parar', no hace la diferencia al agregar -erroracción Detener. El código anterior capta una [Excepción] general, sin embargo, deseo capturar solo la excepción lanzada por el servicio de inicio, lo que significa que podría, por ejemplo, lanzar otra excepción en el bloque de prueba pero no atraparlo en la captura. – Jack

+0

Lo siento, me perdí esa parte. Actualicé el hilo, compruébalo. –

0

descubrir su excepción que puede utilizar:

try 
{ 
    start-service "SomeUnStartableService" -ea Stop 
} 
catch 
{ 
$_.exception.gettype().fullname 
} 

Editado: He aquí una especie de bypass con SystemException

try 
{ 
    start-service "SomeUnStartableService" -ea Stop 
} 
catch [SystemException] 
{ 
write-host "got here" 
} 
+0

Esto devuelve Microsoft.PowerShell.Commands.ServiceCommandException, que es lo que intentaba atrapar arriba. – Jack

+0

La edición ayuda y supongo que encaja en el propósito, así que la he votado, pero no creo que pueda ser la respuesta, ya que es una solución alternativa. – Jack

Cuestiones relacionadas