2012-09-06 27 views
5

Ich schreibe ein VB-Skript, um einige Dateien im Netzwerk zu aktualisieren. Bevor ich anfange, möchte ich wissen, ob eine der Dateien gesperrt ist. Ich würde gerne tun vor Ich mache eigentlich irgendwelche Updates.Wie kann ich feststellen, ob eine Datei mit VBS gesperrt ist?

Ich bin mir bewusst, dass ich den Fehler behandeln kann, wenn die Datei gesperrt ist, wenn ich versuche, es zu ersetzen, aber ich möchte wirklich wissen, ob Dateien gesperrt sind, bevor ich Dateien zu aktualisieren.

Gibt es eine Möglichkeit zu sehen, dass eine Datei mit VBS gesperrt ist (abgesehen von dem Versuch, es zu ersetzen)?

Antwort

11

Diese Funktion legt fest, ob auf eine interessierende Datei im Schreibmodus zugegriffen werden kann. Dies ist nicht genau dasselbe wie zu bestimmen, ob eine Datei von einem Prozess gesperrt ist. Dennoch können Sie feststellen, dass es für Ihre Situation funktioniert. (Zumindest bis etwas Besseres herauskommt.)

Diese Funktion zeigt an, dass der Schreibzugriff nicht möglich ist, wenn eine Datei von einem anderen Prozess gesperrt wird. Diese Bedingung kann jedoch nicht von anderen Bedingungen unterschieden werden, die den Schreibzugriff verhindern. Beispielsweise ist der Schreibzugriff auch nicht möglich, wenn für eine Datei das schreibgeschützte Bit gesetzt ist oder restriktive NTFS-Berechtigungen vorhanden sind. Alle diese Bedingungen führen dazu, dass die Berechtigung verweigert wird, wenn ein Schreibzugriff versucht wird.

Beachten Sie außerdem, dass die von dieser Funktion zurückgegebene Antwort nur dann zuverlässig ist, wenn eine Datei von einem anderen Prozess gesperrt wird. So sind Nebenläufigkeitsprobleme möglich.

Eine Ausnahme wird ausgelöst, wenn eine der folgenden Bedingungen gefunden wird: 'Datei nicht gefunden', 'Pfad nicht gefunden' oder 'ungültiger Dateiname' ('falscher Dateiname oder ungültige Nummer').

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

Darin stellt fest (in anderer Antwort), dass dieses Modul enthalten soll: 'Konst ForReading = 1, ForWriting = 2, ForAppending = 8' – Smandoli

+0

@Smandoli - Vielen Dank für diese Auslassung, um meine Aufmerksamkeit zu bringen. Ich habe den Code entsprechend aktualisiert. Beachten Sie auch meinen Kommentar vor dem Setzen von 'oFile' und' oFso' auf 'Nothing' am Ende der Funktion. – DavidRR

2

Beispiel funktioniert groß, aber müssen Sie die folgende oder auch 5 (Illegal Verfahren) nach, dass

Const ForReading = 1, ForWriting = 2, ForAppending = 8 
+1

Dies scheint für die Antwort von DavidRR zu gelten. Sieht gut zu mir aus. – Smandoli

3

Das Skript unten versucht, für 30 Sekunden in eine Datei zu schreiben und aufgibt erhalten irren. Ich brauchte das, wenn alle unsere Benutzer auf ein Skript klicken mussten. Wahrscheinlich versuchen mehrere Benutzer gleichzeitig zu schreiben. OpenCSV() versucht, die Datei 30 Mal mit einer Verzögerung von 1 Sekunde dazwischen zu öffnen.

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