13

Мне было интересно, если есть инструмент командной строки, который позволяет мне закрыть все файловые дескрипторы, которые открыты в определенной папке.

Я пробовал ProcessExplorer, Unlocker и аналогичные инструменты, но они предлагают интерфейс с графическим интерфейсом и не полезны в среде программирования

Решение на Python, cmd или PowerShell было бы идеальным.

8 ответов8

9

Спасибо за это. У нас возникли некоторые проблемы с дескрипторами открытых файлов, которые приводили к сбою проверок git в наших заданиях Jenkins на базе Windows, и это помогло легко устранить проблему. Я выкину основы техники:

  1. Установите Handle.exe на узел сборки. Я загрузил его отсюда http://technet.microsoft.com/en-us/sysinternals/bb896655, разархивировал и удалил файл Handle.exe в C:\Windows\System32, чтобы убедиться, что он будет доступен по умолчанию% PATH%

  2. Установите плагин Jenkins pre-scm-buildstep: https://wiki.jenkins-ci.org/display/JENKINS/pre-scm-buildstep. Это позволяет нам определять операции до того, как плагин git начал достигать потенциально заблокированных файлов.

  3. В качестве шага сборки перед scm реализована следующая пакетная команда:

    @echo off
    echo Cleaning up open file handles from %NODE_NAME%:%WORKSPACE%...
    for /f "tokens=3,6,8 delims=: " %%i in ('Handle /accepteula %WORKSPACE% ^| grep workspace') do echo Releasing file lock on E:%%k & handle -c %%j -y -p %%i
    

Похоже, что работает хорошо и определенно сокращает ложные сбои. Также отмечу пару ошибок, с которыми я работал:

  • Handler.exe имеет лицензионное соглашение, которое должно быть принято при первом запуске. Если вы используете агент Jenkins в качестве службы в контексте локальной системы, это проблематично, поскольку вы не можете войти в систему под этим пользователем и принять его вручную. Когда мы попытались запустить его из задания Jenkins, процесс просто завис в ожидании ввода данных пользователем, и потребовалось несколько минут, чтобы выяснить, почему. Я решил это, запустив его из задания Jenkins с использованием флага /accepteula, и я рекомендую всем, кто реализует это как автоматизированный процесс, сделать то же самое. Это происходит с параметром реестра в HKEY_CURRENT_USER\Software\Sysinternals\Handle, и вы также можете установить и сбросить его с помощью regedit.exe, если вам нужно манипулировать им для конкретного пользователя, но вариант командной строки показался проще.

  • Плагин Jenkins Batch step выполняет пакетный код, как если бы он был в скрипте, а не в качестве директивы командной строки. Обратите внимание на экранирование (например, %% i, ^ |).

Спасибо!

8

Мы используем следующий фрагмент, чтобы закрыть дескриптор файла от пользователей к нашему серверу. Вы можете изменить его для своего использования.

rem close all network files that are locked
for /f "skip=4 tokens=1" %%a in ('net files') do net files %%a /close
7

Unlocker утверждает, что дает вам эту способность:

  1. Просто щелкните правой кнопкой мыши папку или файл и выберите Unlocker

    Шаг 1

  2. Если папка или файл заблокированы, появится окно со списком шкафчиков

    Шаг 2

  3. Просто нажмите Unlock All и все готово!

Я не уверен, поддерживает ли он использование командной строки.

FileASSASSIN MalwareByte в выполняет аналогичные действия, и поддерживает использование командной строки, так что вы должны быть в состоянии сценария это довольно легко.

FileAssassin's Switches

4

Если вы говорите о дескрипторах файлов, открытых через общий ресурс SMB на файловом сервере Windows (Server 2012 или новее), вот ответ PowerShell:

Get-SmbOpenFile | Where-Object { $_.Path -like "D:\Folder\*" } | Close-SmbOpenFile -Force

На более старом файловом сервере Windows это openfiles.exe /disconnect .

Для дескриптора локального системного файла лучший способ, который я нашел, это использовать Sysinternals handle.exe.

4

Я создаю этот маленький командный файл для автоматического снятия всех блокировок в XML-файл по моему затмению

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\ ^| grep .xml') do echo Releasing %%k & handle -c %%j -y -p %%i

Вам нужно скачать утилиту handle с сайта Microsoft и утилиту grep из GnuWin32

Если вам не нужен фильтр по типу файла, вы можете пропустить часть grep следующим образом:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i

Или, если вам не нужно фильтровать блокировки определенной программой, просто удалите фильтр процесса eclipse:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i

Не забудьте заменить e:\git\ на путь к вашей папке.

3

Если вы используете PSTools, это приведет к рекурсивному закрытию всех открытых файлов:

psfile \\serverName c:\path\toDatabase\ -c

Обратите внимание, что c:\path\toDatabase\ - это диск C: \\serverName , а не ваш локальный компьютер. Сначала это было неясно для меня, поэтому я решил указать на это.

Это метод грубой силы, который почти наверняка потеряет данные, поэтому используйте его с осторожностью.

У нас есть плохо скомпонованная база данных Access, которая буквально регулярно ставит нашу компанию на колени (мне пришлось исправлять ее три раза только вчера).

Парень, который обычно обрабатывает это, находится в отпуске в течение нескольких недель, и его инструкции используют подход, основанный на интерфейсе пользователя (Пуск> Компьютер> Управление> Управление компьютером (локальный)> Подключиться к другому компьютеру> Системные инструменты> Общие папки> Открытые файлы> Открыть Открытые файлы). Слишком много щелчков мышью, когда я могу просто выполнить указанную выше команду и выкинуть всю компанию из всех файлов базы данных и запустить процесс Compact & Repair (к которому я также работаю над подходом, основанным на скрипте с использованием грубой силы).

Хитрость заключается в том, чтобы опередить людей, которые сразу же начинают переподключаться к базе данных, как только она выходит из строя. Они настолько привыкли к этому, что им и в голову не приходит подавать ошибку, они просто продолжают забивать базу данных, пока не вернутся обратно. Я просто продолжаю загружать их, пока не сожму и не восстановлю три десятка файлов, которые составляют базу данных.

2

Unlocker может работать и в беззвучном режиме.

Например, чтобы разблокировать все файлы в рабочем пространстве Jenkins:

"C:\Program Files\Unlocker\unlocker.exe" "%WORKSPACE%" /S

Затем вы можете безопасно удалить файлы рабочей области:

del "%WORKSPACE%\*.*" /s /q
1

Я предпочитаю http://lockhunter.com, потому что он поддерживает как графический интерфейс, так и интерфейс командной строки, и во многих случаях смог удалить файлы, которые не удалось удалить с помощью Unlocker.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .