Скрипт PowerShell для проверки приложения, которое блокирует файл? - PullRequest
44 голосов
/ 06 июня 2009

Используя в PowerShell, как я могу проверить, блокирует ли приложение файл?

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

Ответы [ 7 ]

37 голосов
/ 06 июня 2009

Вы можете сделать это с помощью SysInternals tool handle.exe . Попробуйте что-то вроде этого:

PS> $handleOut = handle
PS> foreach ($line in $handleOut) { 
        if ($line -match '\S+\spid:') {
            $exe = $line
        } 
        elseif ($line -match 'C:\\Windows\\Fonts\\segoeui\.ttf')  { 
            "$exe - $line"
        }
     }
MSASCui.exe pid: 5608 ACME\hillr -   568: File  (---)   C:\Windows\Fonts\segoeui.ttf
...
10 голосов
/ 06 июня 2009

Вы можете использовать команду openfiles из обычной командной строки или из PowerShell.

Встроенный инструмент openfiles может использоваться для общих файлов или для локальных файлов. Для локальных файлов необходимо включить инструмент и перезагрузить компьютер (опять же, только для первого использования). Я считаю, что команда для включения этой функции:

openfiles /local on

Например (работает в Windows Vista x64):

openfiles /query | find "chrome.exe"

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

9 голосов
/ 22 ноября 2012

Это может помочь вам: Используйте PowerShell, чтобы узнать, какой процесс блокирует файл . Он анализирует свойство System.Diagnostics.ProcessModuleCollection Modules каждого процесса и ищет путь к файлу заблокированного файла:

$lockedFile="C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}}
7 голосов
/ 24 июля 2015

Вы можете найти решение, используя Sysinternal 's Ручка .

Мне пришлось немного изменить код для работы с PowerShell 2.0:

#/* http://jdhitsolutions.com/blog/powershell/3744/friday-fun-find-file-locking-process-with-powershell/ */
Function Get-LockingProcess {

    [cmdletbinding()]
    Param(
        [Parameter(Position=0, Mandatory=$True,
        HelpMessage="What is the path or filename? You can enter a partial name without wildcards")]
        [Alias("name")]
        [ValidateNotNullorEmpty()]
        [string]$Path
    )

    # Define the path to Handle.exe
    # //$Handle = "G:\Sysinternals\handle.exe"
    $Handle = "C:\tmp\handle.exe"

    # //[regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\b(\d+)\b)\s+type:\s+(?<Type>\w+)\s+\w+:\s+(?<Path>.*)"
    # //[regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+\w+:\s+(?<Path>.*)"
    # (?m) for multiline matching.
    # It must be . (not \.) for user group.
    [regex]$matchPattern = "(?m)^(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+(?<User>.+)\s+\w+:\s+(?<Path>.*)$"

    # skip processing banner
    $data = &$handle -u $path -nobanner
    # join output for multi-line matching
    $data = $data -join "`n"
    $MyMatches = $matchPattern.Matches( $data )

    # //if ($MyMatches.value) {
    if ($MyMatches.count) {

        $MyMatches | foreach {
            [pscustomobject]@{
                FullName = $_.groups["Name"].value
                Name = $_.groups["Name"].value.split(".")[0]
                ID = $_.groups["PID"].value
                Type = $_.groups["Type"].value
                User = $_.groups["User"].value.trim()
                Path = $_.groups["Path"].value
                toString = "pid: $($_.groups["PID"].value), user: $($_.groups["User"].value), image: $($_.groups["Name"].value)"
            } #hashtable
        } #foreach
    } #if data
    else {
        Write-Warning "No matching handles found"
    }
} #end function

Пример:

PS C:\tmp> . .\Get-LockingProcess.ps1
PS C:\tmp> Get-LockingProcess C:\tmp\foo.txt

Name                           Value
----                           -----
ID                             2140
FullName                       WINWORD.EXE
toString                       pid: 2140, user: J17\Administrator, image: WINWORD.EXE
Path                           C:\tmp\foo.txt
Type                           File
User                           J17\Administrator
Name                           WINWORD

PS C:\tmp>
0 голосов
/ 02 апреля 2015

Мне нравится то, что имеет командная строка (CMD), и она также может использоваться в PowerShell:

tasklist /m <dllName>

Просто обратите внимание, что вы не можете ввести полный путь к файлу DLL. Просто имя достаточно хорошее.

0 голосов
/ 18 сентября 2012

Если вы слегка измените вышеуказанную функцию, как показано ниже, она вернет True или False (вам нужно будет выполнить с полными правами администратора) например Использование:

PS> TestFileLock "c: \ pagefile.sys"

function TestFileLock {
    ## Attempts to open a file and trap the resulting error if the file is already open/locked
    param ([string]$filePath )
    $filelocked = $false
    $fileInfo = New-Object System.IO.FileInfo $filePath
    trap {
        Set-Variable -name Filelocked -value $true -scope 1
        continue
    }
    $fileStream = $fileInfo.Open( [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None )
    if ($fileStream) {
        $fileStream.Close()
    }
    $filelocked
}
0 голосов
/ 15 сентября 2012

Я видел хорошее решение в Обнаружение заблокированных файлов , которое использует только классы PowerShell и .NET Framework:

function TestFileLock {
    ## Attempts to open a file and trap the resulting error if the file is already open/locked
    param ([string]$filePath )
    $filelocked = $false
    $fileInfo = New-Object System.IO.FileInfo $filePath
    trap {
        Set-Variable -name filelocked -value $true -scope 1
        continue
    }
    $fileStream = $fileInfo.Open( [System.IO.FileMode]::OpenOrCreate,[System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None )
    if ($fileStream) {
        $fileStream.Close()
    }
    $obj = New-Object Object
    $obj | Add-Member Noteproperty FilePath -value $filePath
    $obj | Add-Member Noteproperty IsLocked -value $filelocked
    $obj
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...