2009-06-05 4 views

Antwort

28

Sie können dies mit der SysInternals tool handle.exe tun. Probieren Sie etwas wie folgt aus:

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 
... 
+7

Danke, ich kann einfach handle [Dateiname] verwenden, um es einfacher zu machen. –

+0

Wo ist der Spaß dabei? :-) Aber ja, das wäre viel einfacher. –

+0

:(immer noch Probleme mit ... Es ist nicht so leistungsfähig zu zeigen, wenn Dateien (dh Textdateien) durch einen bestimmten Prozess geöffnet werden. –

9

Sie können die openfiles command entweder über die normale Befehlszeile oder über PowerShell verwenden.

Das integrierte Tool "openfiles" kann für Dateifreigaben oder für lokale Dateien verwendet werden. Für lokale Dateien müssen Sie das Tool einschalten und den Computer neu starten (nur für die erstmalige Verwendung). Ich glaube, dass der Befehl diese Funktion aktivieren ist:

openfiles /local on 

Zum Beispiel (funktioniert unter Windows Vista x64  ):

openfiles /query | find "chrome.exe" 

die erfolgreich Datei zurückgibt Griffe mit Chrome verbunden. Sie können auch einen Dateinamen eingeben, um den Prozess zu sehen, der gerade auf diese Datei zugreift.

+0

Von dem, was ich sehe, dass Befehl einfach aufzählt Dateien, die von von einem Benutzer geöffnet werden remote über SMB-Aktien. Es wird Ihnen nichts über den Prozess erzählen, der es benutzt. – Joey

+0

Sie können es nicht von dem Link erzählen, aber es sieht so aus, als ob Johannes recht hat. Es funktioniert nicht auf Vista x64 für mich - sagt "INFO: Keine freigegebenen geöffneten Dateien gefunden." –

+0

Joe/Johannes: Erstens, haben Sie die globale "Liste der verwalteten Objekte" aktiviert (ich denke, die Syntax ist "openfiles/local on" IIRC)? Als nächstes übergeben Sie das Argument "/ query", wie im obigen Beispiel (für Vista erforderlich)? – Garrett

3

ich eine schöne Lösung bei Locked file detection gesehen haben, die nur Powershell und .NET Framework-Klassen verwendet:

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 
} 
+0

Sorry, ich gab eine Antwort auf ein anderes Szenario :( – Jordij

+0

Dies zeigt nur, wenn die Datei gesperrt ist oder nicht, es zeigt nicht, welcher Prozess es verwendet. – KERR

0

Wenn Sie die obige Funktion etwas ändern wie darunter gibt True oder False zurück (Sie müssen mit vollen Admin-Rechten ausführen) eg Verbrauch:

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 
} 
+3

This gibt an, ob die Datei gesperrt ist oder nicht, gibt aber nicht die Anwendung, die die Datei sperrt – CJBS

+2

Zusätzlich: Es wird * eine * neue * Datei erstellen, wenn sie nicht bereits existiert – monojohnny

8

Dies könnte Ihnen helfen: Use PowerShell to find out which process locks a file. Es analysiert die System.Diagnostics.ProcessModuleCollection Module Eigenschaft jeden Prozess und es sieht für den Dateipfad der gesperrten Datei:

$lockedFile="C:\Windows\System32\wshtcpip.dll" 
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}} 
+11

Wäre die perfekte Antwort für mich gewesen, scheint aber, dass dies nur für dlls funktionieren würde und nicht für irgendwelche Dateien, wie gesperrte Textdateien. –

0

Ich mag, was die Eingabeaufforderung (CMD) hat, und es kann in Powershell verwendet werden auch:

tasklist /m <dllName> 

Es genügt zu bemerken, dass Sie nicht den vollständigen Pfad der DLL-Datei eingeben. Nur der Name ist gut genug.

+0

Leider zeigt dies nur DLL-Dateien ... – KERR

4

Sie können eine Lösung mit Sysinternal 's Handle Dienstprogramm finden.

Ich hatte den Code (etwas) ändern mit Powershell arbeiten 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>.*)" 
    [regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+(?<User>\.+)\s+\w+:\s+(?<Path>.*)" 

    $data = &$handle -u $path 
    $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 

Beispiel:

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

Schön, danke fürs Schreiben dieser einfachen Funktion! – Denis

Verwandte Themen