簡體   English   中英

如何檢查文件是否正在被另一個進程使用 - Powershell

[英]How to check if file is being used by another process - Powershell

我試圖找到一個解決方案來檢查文件是否正在被另一個進程使用。 我不想讀取文件的內容,因為在 7GB 的文檔上,這可能需要一段時間。 目前我正在使用下面提到的 function,這並不理想,因為腳本需要大約 5 - 10 分鍾來檢索一個值。

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

任何幫助將不勝感激

我用來檢查文件是否被鎖定的函數:

function IsFileLocked([string]$filePath){
    Rename-Item $filePath $filePath -ErrorVariable errs -ErrorAction SilentlyContinue
    return ($errs.Count -ne 0)
}

創建了一個解決上述問題的函數:

 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
        }
    }
function IsFileAccessible( [String] $FullFileName )
{
  [Boolean] $IsAccessible = $false

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

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

我想更正上面的答案:

 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]::None )
            write-host (getDateTime) "[ACTION][FILEAVAILABLE]" $filePath
            $fileStream.Dispose()
            return $true
        }
        catch
        {
            write-host (getDateTime) "[ACTION][FILELOCKED] $filePath is locked"
            return $false
        }
    }

如果您嘗試使用 [FileShare]::Read 打開文件,如果其他進程也指定了此(或更少限制)FileShare 模式,則可以打開它。 因此,您必須使用 [FileShare]::None,因為限制最多且與任何其他模式不兼容 - 因此,如果文件由另一個進程以任何方式打開,腳本將無法打開它。

還應處理文件流,否則文件可能會無限期地保持打開狀態。

如果您不想閱讀該文件,我建議使用像Sysinternals Handle.exe這樣的實用程序,它會為進程吐出所有打開的句柄。 你可以從這里下載Handle.exe:

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

您可以在沒有任何參數的情況下運行Handle.exe,它將返回所有打開的文件句柄。 您可以根據需要解析輸出,或者只是將輸出與完整文件路徑匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM