I have the following VBScript program to zip up files. It works fine most of the time, except that it seems to occasionally delete a file that it is zipping! This condition is trapped by the script. Can anyone suggest what might be causing this?
Code is:
'
' VBScript to compress all files in a specified directory that match a given prefix and suffix.
' Matching files are compressed to a zip file called <prefix>.zip, created in the same specified directory.
' Option to either keep original files or clobber (delete) them once they've been zipped.
' See Entry Point and usage at foot of files for details and how to invoke.
' Failure is reported by screen output and errorlevel 1, so can be tested from a batch file.
'
' Create a file that looks exactly like an empty zip file
'
Function CreateEmptyZip(folder, zipPrefix)
Dim strZIPHeader
Dim fso
Dim sPath
strZIPHeader = Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0) ' header required to convince Windows shell that this is really a zip file
Set fso = CreateObject("Scripting.FileSystemObject")
sPath = CStr(fso.GetFolder(folder)) & "\" & zipPrefix & ".zip" ' getFolder trims trailing \ if it's there
fso.CreateTextFile(sPath).Write strZIPHeader
Set fso = Nothing
CreateEmptyZip = sPath
End Function
'
' Get files in folder that start with filePrefix and end in fileSuffix.
' Put the matches into outputAry
'
Sub GetMatchingFiles(folder, filePrefix, fileSuffix, outputAry)
Dim fso, f, f1, fc, name, f1Prefix, f1Suffix, count
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(folder)
Set fc = f.Files
count = 0
For Each f1 in fc
f1Prefix = mid(f1, len(f1.ParentFolder)+2, len(filePrefix))
f1Suffix = right(f1, len(fileSuffix))
If f1Prefix = filePrefix and f1Suffix = fileSuffix Then
redim preserve outputAry(count)
outputAry(count) = CStr(f1)
count = count + 1
End If
Next
' put a dummy entry in at the end
redim preserve outputAry(count)
outputAry(count) = ""
Set fc = Nothing
Set f = Nothing
Set fso = Nothing
End Sub
'
' check files are still there
' return a list of those that have vanished
'
Function CheckFilesStillThere(fileList)
Dim fso
Dim fileIx
CheckFilesStillThere = ""
Set fso = CreateObject("Scripting.FileSystemObject")
For fileIx = Lbound(fileList) to Ubound(fileList) - 1
If Not fso.FileExists(fileList(fileIx)) Then
If CheckFilesStillThere = "" Then
CheckFilesStillThere = "ERROR: file(s) deleted during Zip: " + fileList(fileIx)
Else
CheckFilesStillThere = CheckFilesStillThere + ", " + fileList(fileIx)
End If
End If
Next
Set fso = Nothing
End Function
'
' key function: find files in folder that start with filePrefix and end in fileSuffix, and
' put them into a zip file.
'
Function ZipThem(folder, filePrefix, fileSuffix)
Dim shellApp
Dim ns
Dim fileList()
Dim addCount
Dim fileIx
Dim zipFile
Dim timeoutSecs
ZipThem = "" ' empty string denotes success
Call GetMatchingFiles(folder, filePrefix, fileSuffix, fileList)
' there is no length operation for arrays !!!
If UBound(fileList) = LBound(fileList) Then
'MsgBox "No files to process"
Exit Function
End If
' otherwise press on
zipFile = CreateEmptyZip(folder, filePrefix)
Set shellAp = CreateObject("Shell.Application")
Set ns = shellAp.Namespace(zipFile)
addCount = 0
For fileIx = Lbound(fileList) to Ubound(fileList) - 1
ns.CopyHere fileList(fileIx) ' <=== this copies a file to the Zip file
addCount = addCount + 1
' wait for it to finish
timeoutSecs = 0
While (ns.items.count <> addCount)
' give it a second
wscript.sleep(1000)
timeoutSecs = timeoutSecs + 1
' after 5 minutes, something is wrong
If timeoutSecs = 300 Then
ZipThem = "ERROR: Zip Timed Out"
Set ns = Nothing
Set shellAp = Nothing
Exit Function
End If
Wend
Next
Set ns = Nothing
Set shellAp = Nothing
' have seen cases where files are removed by this operation !!
ZipThem = CheckFilesStillThere(fileList)
If ZipThem <> "" Then
Exit Function
End If
End Function
' Entry Point
Dim usage
Dim result
usage = "Usage: CompressFiles folder file_prefix extension"
If WScript.Arguments.Count <> 3 Then
WScript.echo usage
WScript.Quit(1)
Else
result = ZipThem(WScript.Arguments.Item(0), WScript.Arguments.Item(1), WScript.Arguments.Item(2))
If result = "" Then
WScript.Quit(0)
Else
WScript.echo result
WScript.Quit(1)
End If ' result of ZipThem
End If ' argc != 3