6

ネットワーク上のいくつかのファイルを更新する VB スクリプトを作成しています。始める前に、ロックされているファイルがあるかどうかを知りたいです。実際に更新を行う前にこれを行いたいと思います。

ファイルを置き換えようとしたときにファイルがロックされている場合、エラーを処理できることは承知していますが、ファイルの更新を開始する前に、ファイルがロックされているかどうかを知りたいと思っています。

ファイルが VBS を使用してロックされていることを確認する方法はありますか (ファイルを置き換えようとする以外に)。

4

3 に答える 3

12

この関数は、対象のファイルに「書き込み」モードでアクセスできるかどうかを判別します。これは、ファイルがプロセスによってロックされているかどうかを判断することとまったく同じではありません。それでも、あなたはそれがあなたの状況のた​​めに働くことに気付くかもしれません。(少なくとも何か良いことが起こるまで。)

この関数は、ファイルが別のプロセスによってロックされている場合、「書き込み」アクセスが不可能であることを示します。ただし、その条件を「書き込み」アクセスを妨げる他の条件と区別することはできません。たとえば、ファイルに読み取り専用ビットが設定されているか、制限付きの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
于 2012-09-07T01:52:19.757 に答える
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
于 2013-11-20T11:12:47.767 に答える