2012-02-22 19 views
5

Próbuję znaleźć rozwiązanie, które sprawdzi, czy plik jest używany przez inny proces. Nie chcę czytać zawartości pliku, jak w przypadku dokumentu o pojemności 7 GB, może to chwilę potrwać. Obecnie korzystam z funkcji wspomnianej poniżej, co nie jest idealne, ponieważ do pobrania wartości skrypt zajmuje około 5-10 minut.Jak sprawdzić, czy plik jest używany przez inny proces - Powershell

function checkFileStatus($filePath) 
{ 
    write-host (getDateTime) "[ACTION][FILECHECK] Checking if" $filePath "is locked" 

    if(Get-Content $filePath | select -First 1) 
    { 
     write-host (getDateTime) "[ACTION][FILEAVAILABLE]" $filePath 
     return $true 
    } 
    else 
    { 
     write-host (getDateTime) "[ACTION][FILELOCKED] $filePath is locked" 
     return $false 
    } 
} 

Każda pomoc będzie bardzo mile widziane

Odpowiedz

5

utworzono funkcję, która rozwiązuje powyższy problem:

function checkFileStatus($filePath) 
    { 
     write-host (getDateTime) "[ACTION][FILECHECK] Checking if" $filePath "is locked" 
     $fileInfo = New-Object System.IO.FileInfo $filePath 

     try 
     { 
      $fileStream = $fileInfo.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read) 
      write-host (getDateTime) "[ACTION][FILEAVAILABLE]" $filePath 
      return $true 
     } 
     catch 
     { 
      write-host (getDateTime) "[ACTION][FILELOCKED] $filePath is locked" 
      return $false 
     } 
    } 
+0

Dziękuję bardzo za Twój kod. To jest bardzo użyteczne. Używam go do sprawdzenia, czy plik w udostępnionej lokalizacji sieciowej jest dostępny do użytku. Co kilka dni przesyłają nowy duży plik do tej lokalizacji (co zajmuje kilka godzin) i chcę się upewnić, że przesyłanie zostało zakończone, aby bezpiecznie skopiować i pobrać ten plik na mój komputer lokalny. Czy widzisz jakąś wadę w mojej koncepcji? – FrozenLand

+0

Czy jest jakiś powód, że to nie wywołuje '$ fileStream.Dispose()' przed wyjściem? – user2426679

+0

@ user2426679 Czytałem, że garbage collector zajmie się tym, chyba że tworzysz zbyt wiele obiektów w określonym czasie. –

1

Sprawdź ten skrypt na poschcode.org:

filter Test-FileLock { 
    if ($args[0]) {$filepath = gi $(Resolve-Path $args[0]) -Force} else {$filepath = gi $_.fullname -Force} 
    if ($filepath.psiscontainer) {return} 
    $locked = $false 
    trap { 
     Set-Variable -name locked -value $true -scope 1 
     continue 
    } 
    $inputStream = New-Object system.IO.StreamReader $filepath 
    if ($inputStream) {$inputStream.Close()} 
    @{$filepath = $locked} 
} 
+0

FYI, że nie jest to ogniwo PoshCode. –

+0

Naprawiony, nieprawidłowy URL do wklejenia –

+0

Dzięki, dzięki pomocy linku, stworzyłem nową funkcję, która robi to, co wymagane. – user983965

0

ponieważ nie chcą czytać plik, polecam użyciu narzędzie jak Sysinternals Handle .exe, który wypluje wszystkie otwarte uchwyty dla procesu. Można pobrać Handle.exe stąd:

http://technet.microsoft.com/en-us/sysinternals/bb896655

można uruchomić Handle.exe bez żadnych argumentów, a będzie to powrót wszystkich otwartych uchwytów plików. W razie potrzeby można przeanalizować dane wyjściowe lub po prostu dopasować wynik do pełnej ścieżki do pliku.

3

Funkcja mogę używać, aby sprawdzić, czy plik jest zablokowany lub nie:

 
function IsFileLocked([string]$filePath){ 
    Rename-Item $filePath $filePath -ErrorVariable errs -ErrorAction SilentlyContinue 
    return ($errs.Count -ne 0) 
} 
-1
function IsFileAccessible([String] $FullFileName) 
{ 
    [Boolean] $IsAccessible = $false 

    try 
    { 
    Rename-Item $FullFileName $FullFileName -ErrorVariable LockError -ErrorAction Stop 
    $IsAccessible = $true 
    } 
    catch 
    { 
    $IsAccessible = $false 
    } 
    return $IsAccessible 
} 
+0

Dodaj komentarze do swojej odpowiedzi. – HDJEMAI

Powiązane problemy