Handle.exe или как разблокировать файл

Думаю нет среди моих читателей человека, который не сталкивался бы с проблемой файлов “залоченных” другими процессами. Ситуация вобщем то простая, и естественная – программа, для работы с файлом, открывает его с доступом на запись, или для монопольного чтения. Подробности наверное интерисуют лишь программистов, а нам важно понять что за процесс открыл этот файл, и как его освободить. Для этого я обычно использую утилиту от SysinternalsHandle.exe.

К примеру, захотелось мне удалить один файлик…

PS Q:\temp> del .\wlan-870isr.pdf
Remove-Item : Cannot remove item Q:\temp\wlan-870isr.pdf: 
The process cannot access the file 'Q:\temp\wlan-870isr.pdf'
because it is being used by another process.

Не очень приятная ситуация, особенно если удалить файл очень надо, а процесс который его открыл – неизвестен. Ничего страшного, просто скармливаем имя файла (или его часть) утилите:

PS Q:\temp> handle wlan-870isr.pdf

Handle v3.41
Copyright (C) 1997-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

AcroRd32.exe       pid: 3656    278: Q:\temp\wlan-870isr.pdf

Вот теперь нам известен виновник! Можно конечно просто завершить процесс Acrobat Reader’а, и все открытые им файлы будут освобождены:

PS Q:\temp> Stop-Process -Id 3656 -WhatIf
What if: Performing operation "Stop-Process" on Target "AcroRd32 (3656)".

Но что если мы не хотим завершать процесс, но при этом уверены что файл этой программе не нужен и она просто забыла его закрыть? Можно просто принудительно закрыть ссылку на файл (handle). Разумеется этого делать не рекомендуется если вы не уверены что всё кончится хорошо. Программа будет предполагать что файл всё еще открыт ею, и это может привести к неожиданным ошибкам. Но если очень хочется – то можно 😉

PS Q:\temp> handle -p 3656 -c 278

Handle v3.41
Copyright (C) 1997-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

  278: File  (---)   Q:\temp\wlan-870isr.pdf
Close handle 278 in AcroRd32.exe (PID 3656)? (y/n) y

Handle closed.

Вот и готово. После этого, Acrobat Reader даже дал мне полистать несколько страниц документа, правда потом выдал ожидаемую ошибку 🙂

image

Возможно вам повезет больше 😉 Иногда эта функция действительно бывает полезна.

Кстати чтобы handle.exe не переспрашивал вас, можно добавить ключ –y

Опубликовано в SysInternals. Метки: , , , . 4 комментария »

Квадратные скобки в именах файлов

Вы наверное знаете, что в PowerShell, в качестве подстановочных знаков можно использовать не только ? и * как в cmd.exe, но и группы символов в квадратных скобках, например так:

substsquare

Читать далее…

Особенности Net.exe Share

Продолжаю тему использования старых утилит с “особенным” синтаксисом из PowerShell. Следующий пациент – это Net share. Основной функционал этой команды вполне работает при вызове из PowerShell, но…

По умолчанию общие папки начиная с WIndows 2003 (если не ошибаюсь) создаются с разрешением everyone=read. Однако одной из рекомендованных практик раздачи разрешений является выдача на доступ к общей папке everyone=full control, и раздача необходимых разрешений уже средствами NTFS. Это сильно упрощает администрирование, так как не приходится сверять оба списка доступа.

Если посмотреть справку к команде net share то видно что разрешение можно задавать непосредственно в момент создания общей папки:

PS C:\Windows\System32> net share /?
The syntax of this command is:

NET SHARE
sharename
          sharename=drive:path [/GRANT:user,[READ | CHANGE | FULL]]
                               [/USERS:number | /UNLIMITED]
                               [/REMARK:"text"]
                               [/CACHE:Manual | Documents| Programs | None ]
          sharename [/USERS:number | /UNLIMITED]
                    [/REMARK:"text"]
                    [/CACHE:Manual | Documents | Programs | None]
          {sharename | devicename | drive:path} /DELETE
          sharename \\computername /DELETE

Однако если попробовать выполнить такую команду в PowerShell, у нас ничего не получится. Ну точнее net выведет справку по синтаксису, будто мы что то сделали неправильно…:

PS C:\Windows\System32> net share myshare=Q:\temp /GRANT:everyone,FULL
The syntax of this command is:
...

Что интересно, если запустить cmd.exe и выполнить в нём ту же команду, то всё отрабатывает прекрасно. В чем же дело? Выяснить как эта команда выглядит для net.exe поможет файл testargs.cmd который я описал в предыдущем посте из серии:

PS C:\Windows\System32> c:\root\testargs.cmd share myshare=Q:\temp /GRANT:everyone,FULL
Arg1: [share]
Arg2: [myshare]
Arg3: [Q:\temp]
Arg4: [/GRANT:everyone]
Arg5: [FULL]

Теперь хорошо видно что PowerShell посчитал /GRANT:everyone,FULL массивом из двух строк (из за запятой), и передал их утилите по отдельности. Избежать этого опять же несложно, либо замаскировать запятую с помощью обратного апострофа:

PS C:\Windows\System32> net share myshare=Q:\temp /GRANT:everyone`,FULL
myshare was shared successfully.

либо заключить последний параметр в кавычки.

PS C:\Windows\System32> net share myshare=Q:\temp "/GRANT:everyone,FULL" 
myshare was shared successfully.

Как видите всё достаточно просто 🙂

Опубликовано в Command line parsing. Метки: , , , , . 1 Comment »

Bcdedit.exe из PowerShell

Недавно я столкнулся с необходимостью отредактировать элементы загрузки с помощью утилиты bcdedit.exe. Эта утилита используется в системах начиная с Vista, для управления хранилищем конфигурации загрузки, которое заменило boot.ini.

Разумеется я решил запускать утилиту из PowerShell (так как дело происходило на Windows Server 2008R2, то PowerShell было запустить даже проще и быстрее чем cmd.exe 😉 ).

Читать далее…

Опубликовано в Command line parsing. Метки: , , . 5 комментариев »