Hello everyone,
since Gork was so nice to give me a hint on how to schedule backups for a monthly incremental cycle as you can read here. I set up backup tasks using VBScript and scheduled them.
Both tasks were scheduled to run at a certain time and to start immediately if that scheduled start has been missed.
This morning the tasks started at the same time (as expected), because they missed their scheduled start, but I got a VBScipt error from the second task.
The error occurred at the following spot in the VBScript code:
' Log to file
strLogFileName = "C:\Users\norritt\Documents\Reflect\log-" & Year(Date) & "-" & Month(Date) & "-" & Day(Date) & " " & Hour(Time) & "." & Minute(Time) & "." & Second(Time) & ".txt"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objNewFile = objFS.OpenTextFile(strLogFileName , 8, 1)
What happened?
Since both tasks started at the same time, both tried to open the same log file at the same time. Whatever script is faster will be granted exclusive write acces to the log, thus causing the second script to throw an error (Operation not permitted).
Basically I see a couple of ways to fix that:
1. Include the scheduled backup job name in the log file name, that way each task will have its own log file name.
2. Check for log file write access before opening it and in case the log is opened by another task append a consecutive number to the generated name till you generate a file name that is not yet in use (this will be my workaround for the time being). Could look something like that:
Function Backup(Byref strCmdLine)
...
Dim intCNo
' Log to file
...
Dim intCNo
Dim intExtStart
Dim strLogFileName
Dim strLogFilePrefix
Dim strLogFileExtension
intCNo = 0
'Seperate log file extension from log file name.
intExtStart = InStrRev(strLogFileName, ".")
strLogFilePrefix = Left(strLogFileName, (intExtStart - 1))
strLogFileExtension = Right(strLogFileName, Len(strLogFileName) - (intExtStart - 1))
Set objFS = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Do
Err.Number = 0
Set objNewFile = objFS.OpenTextFile(strLogFilePrefix & "_" & CStr(intCNo) & strLogFileExtension, 8, 1)
intCNo = intCNo + 1
Loop Until Err.Number = 0 Or intCNo > 99 'Stop after 99 retries, maybe we don't have folder write access at all.
If intCNo > 99 Then
MsgBox "Error writing to logfile: " & strLogFilePrefix & "_" & CStr(intCNo) & strLogFileExtension & "."
End If
On Error GoTo 0
Do Until objExecObject.StdOut.AtEndOfStream
strLine = objExecObject.StdOut.ReadLine()
If Instr(strLine , "%") = 0 Then
objNewFile.WriteLine strLine
end if
Loop
objNewFile.Close
...
End Function
Of course that solution could be improved a bit, for instance left padding the consecutive number with zeroes so it'll have the same length even if > 10 backups start at the same time.
3. This solution is not really elegant, since it requires some polling and might hang forever if the log folder is not writable for the user executing the backup. But it can be used to write to a single log file though:
Check for log file write access every second and loop till other running tasks have released their write lock on the file.
4. Maybe there is a way to solve this inside the reflect scheduler, by making sure that only one VBScripted job is executed at the same time.
--
Regards norritt