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
}
Спасибо.
Ответы
Ответ 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 здесь или здесь