Иногда при попытке удалить, переименовать или переместить какой-то файл или папку в Windows вы можете получить сообщение, что файл занят/заблокирован/используется другим процессом. Чаще всего имя программы, которая держит файл открытым, указывается прямо в окне сообщения File Explorer. Чтобы снять блокировку с файла, достаточно просто закрыть эту программу. Но бывает ситуации, когда необходимый файл используется (заблокирован) неизвестным или системным процессом.
Если некий процесс или приложение открыло файл в монопольном (эксклюзивном режиме), такой файл блокируется файловой системой от операций ввода/вывода других приложений. При попытке что-то сделать с заблокированным файлом, появится сообщение о том, что файл уже используется.
File/Folder in Use. The action can’t be completed because the file is open in another program. Close the folder or file and try again.
Файл уже используется. Операция не может быть завершена, так как файл или папка открыта в другой программе. Закройте файл и повторите попытку.
В этом примере видно, какое именно приложение заблокировало файл. Чтобы освободить файл, просто закройте это приложение.
Если файл заблокирован операционной системой, или другим процессом, запущенным с правами SYSTEM, сообщение о том, что файл занят, не будет содержать имя конкретного приложения.
The action can’t be completed because the file is open in SYSTEM.
Файл уже используется. Действие не может быть выполнено, так как этот файл открыт в System.
The process cannot access the file XXX because it is being used by another process.
Когда процесс в Windows открывает файл, этому потоку ввода/вывода назначается дескриптор (handler). Процесс и его дочерние процессы получают доступ к файлу по этому дескриптору. Через Window API вы можете послать сигнал файловой системе на освобождение данного дескриптора и снятие блокировки с файла.
Как найти процесс, который заблокировал файл или папку в Windows?
В Windows есть несколько встроенных инструментов, который позволяют определить имя процесса/приложения, которое использует файл в текущий момент.
Для определения файлов, которые открыты процессами, можно использовать Resource Monitor (resmon.exe)
- Запустите
resmon.exe
и перейдите на вкладку CPU - В поисковой строке в разделе Associated Handles укажите имя заблокированного файла или папки
- В окне с результатами поиска появится имя процесса, который использует файл в данный момент.
- Вы можете сразу закрыть этот процесс щелкнув по нему и выбрав End Process.
Как разблокировать файл с помощью Process Explorer?
Не всегда возможно просто завершить процесс, которые заблокировал файл, особенно на серверах. Для поиска процесса, который заблокировал файл и освобождения этого файла без завершения родительского процесса удобно использовать утилиту ProcessExplorer. ProcessExplorer можно скачать с сайта Microsoft или установить с помощью пакетного менеджера WinGet:
Winget install Microsoft.Sysinternals.ProcessExplorer
- Запустите ProcessExplorer (
procexp.exe
) с правами администратора - Выберите меню Find -> Find Handle or DLL (или нажмите
Ctrl-F
); - Укажите имя файла, который нужно разблокировать и нажмите Search
- Выберите нужный файл. Процесс, который открыл файл, будет выделен в дереве процессов.
- Можно завершить этот процесс, щелкнув по нему правой кнопкой и выбрав Kill Process Tree.
- Но можно попробовать закрыть дескриптор файла, не завершая процесс целиком. Дескриптор файла, который вы искали, автоматически выделяется в нижней панели Process Explorer.
- Щелкните по дескриптору правой кнопкой и выберите Close handle. Подтвердите закрытие файлаЧтобы в Process Explorer отображалась нижняя панель со списком открытых дескрипторов процесса, включите пункт View -> Lower Pane View -> Handles
Итак, вы закрыли дескриптор файла, не завершая родительский процесс. Теперь вы можете спокойно удалить или переименовать файл.
Сброс дескриптора открытого файла с помощью Handle
Handle, это консольная утилита Microsoft, которая позволяет найти процесс, который заблокировал ваш файл и снять блокировку, освободив дескриптор.
- Скачайте или установите утилиту Handle через Winget:
winget install Microsoft.Sysinternals.Handle
- Запустите командную строку с правами администратора и выполните команду:
handle.exe > listproc.txt
- Данная команда сохранит список открытых дескрипторов в файл.
- Можно вывести список дескрипторов файлов в определённом каталоге (параметр -u используется, чтобы показать имя пользователя, запустившего процесс):
Handle.exe -u -a C:\Some\Path
Или выведите открытые дескрипторы конкретного процесса (какие файлы и другие объекты держит в открытом состоянии данный процесс):
handle.exe -p winword.exe
- Откройте файл listproc.txt в любом текстовом редакторе и найдите строку, в которой указано имя заблокированного файла. Скопируйте ID дескриптора файла (значение в hex формате). Затем поднимитесь немного выше к разделу, в котором указан процесс, являющийся владельцем данного дескриптора и запишите его ID. Для процесса, запущенного от имени системы скорее всего будет PID 4.Для некоторых системных процессов handle.exe вернет следующий текст:
wininit.exe pid: 732 \<unable to open process>
. Это означает, что вы не может получить информацию об этих системных процессах (даже с правами администратора). Для получения дескрипторов файлов, открытых такими процессами, запустите командную строку с правами System и попробуйте получить список дескрипторов еще раз. - Теперь вернитесь в командную строку и сбросьте дескриптор файла по полученным HandleID и ProcessID. Формат команды следующий:
handl64e.exe -c HandleID -p ProcessID
Например:
handl64e.exe -c 18C -p 18800
- Утилита запросит подтвердить закрытие файла для указанного процесса. Подтвердите, нажав y -> enter
Если система отреагирует на закрытие файла корректно, вы разблокируете ваш файл без необходимости завершать процесс или перезагружать сервер/компьютер.
Для автоматизации поиска процесса, занявшего файл можно использовать такой PowerShell скрипт:
$file = "C:\PS\out_file.txt"
$handleOutput = handle.exe $file
$pidList = @()
$handleOutput | ForEach-Object {
if ($_ -match "^(.*)\s+pid:\s*(\d+)") {
$name = $matches[1].Trim()
$processId = $matches[2]
if ($pidList -notcontains $processId) {
Write-Host "ParentProcess PID $processId $name"
$pidList += $processId
}
}
}
Заблокированные файлы в сетевой папке
Если файл в сетевой папке на компьютере открыт (монопольно занят) по сети (через общую шару, или административный общий ресурс), большинство указанных утилит не покажет, кто использует файл.
Для вывода открытых по сети файлом можно использовать команду:
net file
или
openfiles /query /fo
Чтобы закрыть заблокированный файл, выполните:
net file [id] /close
Подробнее о том, как найти и закрыть открытые файлы в сетевой папке.
А где еще можно скачать Handle? На сайте Microsoft — 404
Впрочем и линк перечеркнут в статье.
ЧИТАТЬ НАДО, прежде чем спрашивать 🙂
Handle – это еще одна утилита командной строки из комплекта инструментов Sysinternals
Вопрос снят.
Да, немного кривая ссылка была. Исправил.
ну да, ссылка ищется в гугле на раз-два 🙂
OK
Есть еще один способ
usually it is because the file is open via file sharing. You can close that in computer management GUI / Shared folders / Open Files or via command line
net file — lists all open files
net file id /close
UPDATE: this command might work better in some cases:
openfiles /query /fo csv /v > c:\temp\files.csv -then open files.csv and search in it-
Взято из
https://superuser.com/questions/52337/how-can-i-unlock-a-folder-locked-by-system-process-on-windows-server-2008
Спасибо. Реально полезняшка.
«net file» и «openfiles» эти команды только для файлов, открытых через SMB Share, а не для всех открытых на компьютере.
Для «openfiles» есть ключ «local».