2012-09-06 7 views
5

VB 스크립트를 작성하여 네트워크의 일부 파일을 업데이트합니다. 시작하기 전에 파일이 잠겨 있는지 알고 싶습니다. 내가 이것을 수행하고 싶습니다 전에 나는 실제로 어떤 업데이 트합니까.VBS를 사용하여 파일이 잠겨 있는지 여부를 어떻게 확인할 수 있습니까?

바꾸려고 할 때 파일이 잠긴 경우 오류를 처리 할 수 ​​있지만 파일을 업데이트하기 전에 모든 파일이 잠겨 있는지 실제로 알고 싶습니다.

VBS를 사용하여 파일을 잠궈 놓은 것을 볼 수있는 방법이 있습니까?

답변

11

이 기능은 관심있는 파일을 '쓰기'모드로 액세스 할 수 있는지 여부를 결정합니다. 이것은 파일이 프로세스에 의해 잠겨 있는지 여부를 결정하는 것과 정확히 같지 않습니다. 그래도 상황에 따라 작동하는 것을 알 수 있습니다. (적어도 뭔가 더 나아질 때까지)

이 기능은 파일이 다른 프로세스에 의해 잠겨있을 때 '쓰기'액세스가 불가능 함을 나타냅니다. 그러나 '쓰기'액세스를 금지하는 다른 조건과 해당 조건을 구별 할 수 없습니다. 예를 들어 파일에 읽기 전용 비트가 설정되어 있거나 제한적인 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 
+1

대린 노트이 모듈이 포함되도록 (다른 대답) : '헌장 ForReading = 1, ForWriting = 2, ForAppending = 8' – Smandoli

+0

@Smandoli - 내 관심이 누락을 가져 주셔서 감사합니다. 그에 따라 코드를 업데이트했습니다. 함수 끝 부분에'oFile'과'oFso'를'Nothing'으로 설정하는 것에 앞서 제 의견을 주목하십시오. – DavidRR

2

예는 큰 작동하지만 스크립트는 다음 30 초 동안 파일에 쓰기를 시도하고 그 후 포기

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

이것은 DavidRR에서 제공하는 답변에 적용되는 것으로 보입니다. 나에게 맞는 것 같아. – Smandoli

3

다음 그렇지 않으면 5 (불법 절차를) 잘못을받을 필요가 없다. 모든 사용자가 스크립트를 클릭해야 할 때이 기능이 필요했습니다. 여러 사용자가 동시에 작성하려고 시도 할 가능성이 있습니다. OpenCSV()는 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 
관련 문제