Как рекурсивно удалить весь каталог, содержащий файлы, используемые другим процессом? - PullRequest
1 голос
/ 07 февраля 2020

Я уже пробовал что-то вроде:

While (Test-Path -Path $destinationApplicationFolder){
    Try{
        Remove-Item -Recurse -Force $destinationApplicationFolder -ErrorAction Stop
    }catch{
        IF((Test-Path -Path $destinationApplicationFolder) -eq $false) {
            Write-Warning "File or directory does not exist."       
        }
        Else {
            #Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq "$destinationApplicationFolder\CC.Core.POCO.dll"){$processVar.Name + " PID:" + $processVar.id}}}
            #Stop-Process $processVar -Force
            Get-Process | ?{$destinationApplicationFolder.path -and (test-path (split-path $destinationApplicationFolder.path -leaf ))} | Stop-Process -whatif
        }
    }
}

Возможно ли это сделать без установки другого программного обеспечения?

1 Ответ

1 голос
/ 08 февраля 2020

Чтобы сформулировать то, что, очевидно, очевидно, явно:

  • Принудительное завершение других процессов с помощью Stop-Process обычно должно быть последним средством,

  • особенно с переключателем -Force, учитывая, что он также завершит процессы других пользователей (если другие пользователи будут подключены к той же машине, возможно удаленно), без предупреждения - при условии, что вы работаете в повышенный сеанс (работает от имени администратора), так как только тогда у вас есть необходимые разрешения.


Если вы готовы принять этот риск, и Предполагается, что единственными процессами, препятствующими удалению вашего поддерева каталога, являются процессы, запускаемые из исполняемых файлов или библиотек DLL , расположенных внутри целевого поддерева , вы можете попробовать:

while (Test-Path $destinationApplicationFolder) {

  try {
    Remove-Item -Recurse -Force $destinationApplicationFolder -ErrorAction Stop
  }
  catch {
    Get-Process | 
      Where-Object { $_.Modules.FileName -like "$destinationApplicationFolder\*" } |
        Stop-Process -ErrorAction Stop -WhatIf
  }

}

Примечание: 1029 * общий параметр в приведенной выше команде просматривает операции. Удалите -WhatIf, как только вы убедитесь, что операция будет выполнять то, что вы хотите.

Примечание :

  • Там также могут быть процессы из исполняемых файлов, расположенных в других местах, которые все еще блокируют удаление, если они имеют открытые дескрипторы для файлов и каталогов в поддереве целевого каталога .

    • Чтобы также идентифицировать их, вы должны два варианта:

      • Использование openfiles.exe /Query

        • openfiles.exe поставляется с Windows, но требует работы openfiles /Local ON с возвышением как одноразовое действие установки.
      • Используйте утилиту загрузки по требованию handle.exe SysInternals, которая в противном случае не требует предварительной настройки.

    • Подробнее см. в этом ответе .

  • Remove-Item -Recurse can обычно сбой даже если нет процессов, блокирующих удаление каталога: Невероятно, но функции WinAPI для удаления файлов / папок по своей природе асинхронны , которые могут вызвать периодические, непредсказуемые сбои - см. этот ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...