用于检查锁定文件的应用程序的PowerShell脚本?

Mar*_*lis 44 powershell scripting filelock

在PowerShell中使用,如何检查应用程序是否锁定文件?

我想检查哪个进程/应用程序正在使用该文件,以便我可以关闭它.

Kei*_*ill 37

您可以使用SysInternals工具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
...
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我可以使用handle [filename],使其更简单. (16认同)
  • 那里的乐趣在哪里?:-)但是,那会简单得多。 (2认同)
  • 不幸的是,handle是一个外部工具 (2认同)

Gar*_*ett 12

您应该能够使用常规命令行或PowerShell中的openfiles命令.

openfiles内置工具可用于文件共享或本地文件.对于本地文件,您必须打开该工具并重新启动计算机(再次,只是第一次使用).我相信打开此功能的命令是:

openfiles /local on
Run Code Online (Sandbox Code Playgroud)

例如(适用于Windows Vista x64):

openfiles /query | find "chrome.exe"
Run Code Online (Sandbox Code Playgroud)

这成功返回与Chrome关联的文件句柄.您还可以传入文件名以查看当前访问该文件的进程.

  • Joe/Johannes:首先,您是否打开了全局“维护对象列表”(我认为语法是“打开文件/本地”IIRC)?接下来,您是否传递了“/query”参数,如上例所示(似乎是 Vista 所要求的)? (2认同)

Ale*_*ici 10

这可以帮助您:使用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}}}
Run Code Online (Sandbox Code Playgroud)

  • 对我来说本来是完美的答案,但似乎这只适用于dll,而不仅仅适用于锁定文本文件等任何文件. (15认同)

mva*_*nle 7

您可以使用SysinternalHandle实用程序找到解决方案.

我不得不修改代码(稍微)以使用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
Run Code Online (Sandbox Code Playgroud)

例:

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>
Run Code Online (Sandbox Code Playgroud)


小智 5

我也在寻找解决方案并遇到了一些问题。

  1. 不想使用外部应用程序
  2. Open Files 需要本地 ON 属性,这意味着系统必须在执行前配置为使用它。

经过广泛的搜索,我找到了。

https://github.com/pldmgg/misc-powershell/blob/master/MyFunctions/PowerShellCore_Compatible/Get-FileLockProcess.ps1

感谢保罗·迪马吉奥

这似乎是纯粹的 powershell 和 .net/C#

  • 似乎不适用于目录:/ (2认同)