2010-06-22 9 views
12

Tengo un script de PS que se inicia cada 5 minutos para buscar carpetas nuevas y moverlas. El problema es que a veces elementos de la carpeta todavía se están escribiendo, en cuyo caso los errores de script con:Powershell: IOException try/catch no funciona

Move-Item: El proceso no puede acceder al archivo porque está siendo utilizado por otro proceso. [Move-Elemento], IOException + FullyQualifiedErrorId: MoveDirectoryItemIOError, Microsoft.PowerShell.Commands.MoveItemCommand

he probado el siguiente bloque try/catch pero todavía errores en la misma línea "Move-Item". ¿Alguna idea de lo que estoy haciendo mal aquí?

  try { 
      Move-Item -Force "$fileString" $fileStringFixed 
      } 
      catch [System.IO.IOException] { 
      return 
      } 

Gracias.

Respuesta

23

Las declaraciones Try/catch solo pueden detectar los errores de terminación (estos generalmente indican un error grave). PowerShell también tiene el concepto de errores no terminantes. El error de archivo en uso que ve es un error que no termina. Esto es bueno desde la perspectiva de que si movía miles de archivos y uno tenía su objetivo en uso, el comando no deja de funcionar. Tu tienes dos opciones aquí. Puede pasar por alto estos errores al establecer el parámetro ErrorAction a SilentlyContinue (valor 0), por ejemplo:

Move-Item foo bar -ea 0 

o puede convertir el error de no poner fin a un error de terminación mediante el establecimiento de este mismo parámetro en 'Stop' y luego utilizar el try/catch aunque no filtrar IOException porque PowerShell envuelve la excepción por ejemplo:

try { move-Item .\About_This_Site.txt vmmap.exe -ea stop } ` 
catch {$_.GetType().FullName} 
System.Management.Automation.ErrorRecord 
+0

¡Eso parece, muchas gracias! – orbitron

+5

O configúrelo globalmente para detenerse: $ ErrorActionPreference = 'Parar' –

0

lo que suele hacer con estas situaciones es utilizar una sentencia switch, funciona para la mayoría de los errores de ninguno de terminación. Algo como esto;

Switch -Regex ($_.exception) { 
     "used by another process" { 
      "Do Something about the error" 
     } 
    Default { 
      "Default Action" 
     } 
} 

Es solo mirar la excepción y hacer algo definido en el bloque de script.

Puede hallar más información sobre los estados de conmutación here o here

1

yo era capaz de resolver esto mediante la adición -ErrorAction Stop al comando Move-Item. Eso parece obligarlo a arrojar un error como estaba previsto, en lugar de hacer lo que quiera.

Cuestiones relacionadas