Подтвердить что ты не робот

Powershell: IOException try/catch не работает

У меня есть PS script, который запускается каждые 5 минут, чтобы проверять новые папки и перемещать их. Проблема в том, что иногда элементы в папке все еще записываются, и в этом случае ошибки script с:

Move-Item: процесс не может получить доступ к файлу, потому что он используется другим процессом. [Move-Item], IOException + FullyQualifiedErrorId: MoveDirectoryItemIOError, Microsoft.PowerShell.Commands.MoveItemCommand

Я пробовал следующий блок try/catch, но все еще ошибки в той же строке "Move-Item". Любые мысли о том, что я здесь делаю неправильно?

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

Спасибо.

4b9b3361

Ответ 1

Операторы try/catch могут только улавливать завершающие ошибки (обычно это указывает на серьезную ошибку). PowerShell также имеет концепцию ошибок, не связанных с завершением. Ошибка в файле, которую вы видите, является ошибкой без конца. Это хорошо с точки зрения того, что если вы перемещаете тысячи файлов, а один использует свою цель, команда не держит его в покое. Здесь у вас есть два выбора. Вы можете игнорировать эти ошибки, установив параметр ErrorAction в SilentlyContinue (значение 0), например:

Move-Item foo bar -ea 0

Или вы можете преобразовать необратимую ошибку в завершающую ошибку, установив этот же параметр в значение "Стоп", а затем использовать try/catch, но не фильтровать с помощью IOException, потому что PowerShell завершает исключение, например:

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

Ответ 2

Я смог решить это, добавив -ErrorAction Stop в команду Move-Item. Кажется, это заставляет его бросать ошибку, как предполагалось, вместо того, чтобы делать то, что она хочет.

Ответ 3

То, что я обычно делаю с этими ситуациями, - это использование оператора Switch, оно работает для большинства исключающих ошибок. Что-то вроде этого;

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

Он просто смотрит на исключение и делает что-то определенное в блоке script.

Подробнее о операторах switch здесь или здесь