如何使用VBS确定文件是否被锁定?

7

我正在编写一个VB脚本来更新网络上的一些文件。在开始之前,我想知道是否有任何文件被锁定。我希望在实际更新之前能够做到这一点。

我知道如果我尝试替换已经被锁定的文件,可以处理错误,但是我真的想知道是否有任何文件被锁定,然后再开始更新任何文件。

除了尝试替换文件之外,有没有使用VBS查看文件是否被锁定的方法?

3个回答

14

此函数确定所需文件是否可以以“写”模式访问。这与确定文件是否被进程锁定并不完全相同,但您可能会发现它对您的情况有效(至少在更好的解决方案出现之前)。

当另一个进程锁定文件时,此函数将表明无法进行“写”访问。然而,它无法将其与其他防止“写”访问的条件区分开来。例如,如果文件具有只读位设置或拥有限制的NTFS权限,也不可能进行“写”访问。所有这些条件都将导致在尝试“写”访问时出现“权限被拒绝”的消息。

还要注意,如果文件被另一个进程锁定,则此函数返回的答案仅在执行函数的那一刻可靠。因此,可能存在并发问题。

如果找到以下任何条件之一,则会抛出异常:“文件未找到”,“路径未找到”或“非法文件名”(“错误的文件名或编号”)。

Function IsWriteAccessible(sFilePath)
    ' Strategy: Attempt to open the specified file in 'append' mode.
    ' Does not appear to change the 'modified' date on the file.
    ' Works with binary files as well as text files.

    ' Only 'ForAppending' is needed here. Define these constants
    ' outside of this function if you need them elsewhere in
    ' your source file.
    Const ForReading = 1, ForWriting = 2, ForAppending = 8

    IsWriteAccessible = False

    Dim oFso : Set oFso = CreateObject("Scripting.FileSystemObject")

    On Error Resume Next

    Dim nErr : nErr = 0
    Dim sDesc : sDesc = ""
    Dim oFile : Set oFile = oFso.OpenTextFile(sFilePath, ForAppending)
    If Err.Number = 0 Then
        oFile.Close
        If Err Then
            nErr = Err.Number
            sDesc = Err.Description
        Else
            IsWriteAccessible = True
        End if
    Else
        Select Case Err.Number
            Case 70
                ' Permission denied because:
                ' - file is open by another process
                ' - read-only bit is set on file, *or*
                ' - NTFS Access Control List settings (ACLs) on file
                '   prevents access

            Case Else
                ' 52 - Bad file name or number
                ' 53 - File not found
                ' 76 - Path not found

                nErr = Err.Number
                sDesc = Err.Description
        End Select
    End If

    ' The following two statements are superfluous. The VB6 garbage
    ' collector will free 'oFile' and 'oFso' when this function completes
    ' and they go out of scope. See Eric Lippert's article for more:
    '   http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/when-are-you-required-to-set-objects-to-nothing.aspx

    'Set oFile = Nothing
    'Set oFso = Nothing

    On Error GoTo 0

    If nErr Then
        Err.Raise nErr, , sDesc
    End If
End Function

2
Darin在另一个答案中指出,此模块应包括以下内容:Const ForReading = 1, ForWriting = 2, ForAppending = 8 - Smandoli
@Smandoli - 感谢您提醒我这个遗漏。我已经相应地更新了代码。请注意,在函数末尾设置oFileoFsoNothing之前,我的注释。 - DavidRR
对我有用。谢谢。只是添加了几行代码来检查文件是否存在:`IsWriteAccessible = False Dim oFso: Set oFso = CreateObject("Scripting.FileSystemObject") If oFso.FileExists(sFilePath) = False Then IsWriteAccessible = True Exit Function End If` - Mike

3
下面的脚本会尝试在30秒内写入文件,超过时间就放弃。当所有用户都需要点击一个脚本时,我需要这个功能。很可能有多个用户同时尝试写入文件。OpenCSV()函数会在每次尝试之间延迟1秒,尝试打开文件30次。
  Const ForAppending = 8

  currentDate = Year(Now) & "-" & Month(Now) & "-" & Day(Now) & " " & Hour(Now) & ":" & Minute(Now) & ":" & Second(Now)
  filepath = "\\network\path\file.csv"
  Set oCSV = OpenCSV( filepath ) 
  oCSV.WriteLine( currentDate )
  oCSV.Close

  Function OpenCSV( path )
    Set oFS = CreateObject( "Scripting.FileSystemObject" )
    For i = 0 To 30
      On Error Resume Next
      Set oFile = oFS.OpenTextFile( path, ForAppending, True )
      If Not Err.Number = 70 Then
        Set OpenCSV = oFile
        Exit For
      End If
      On Error Goto 0
      Wscript.Sleep 1000
    Next
    Set oFS = Nothing
    Set oFile = Nothing
    If Err.Number = 70 Then
      MsgBox "File " & filepath & " is locked and timeout was exceeded.", vbCritical
      WScript.Quit
    End If
  End Function

0
或者更简单的做法是:
假设您已经在 VBS 中有一个名为 FileName 的变量,它包含您想要测试的完整文件路径:
Dim oFso, oFile
Set oFso = CreateObject("Scripting.FileSystemObject")
Set oFile = oFso.OpenTextFile(FileName, 8, True)
If Err.Number = 0 Then oFile.Close

第3行尝试以追加权限打开要测试的文件。例如,它尝试使用写锁定打开文件。

如果使用写锁定打开文件会生成错误,则您的VBS将在第三行出错并停止执行。此时,您从调用VBS的任何位置的错误处理程序应该启动。如果无法获取写锁定,则错误消息将为“拒绝许可”。

如果使用锁定打开文件不会导致错误,则第4行将再次关闭它。现在,您可以打开文件或对其进行任何操作,并确信它没有写锁定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接