使用VBS创建.zip备份,没有硬编码等待计时器(Windows 7)

时间:2017-11-21 23:09:17

标签: windows batch-file vbscript zip backup

我在填充已创建的.zip文件夹时遇到问题(用于将{strong>所有内容从C:\Source备份到C:\Destination中的.zip)。问题出现在ZipCMD.vbs文件中。我现在将描述我的整个过程,最后,我将以粗体描述问题,以及我尝试(和失败)的解决方案。

C:\Source

中存在包含测试数据的文件夹

C:\Destination中,使用记事本中的以下代码创建ZipCMD.vbs(感谢Gerhard Barnard)

Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)
WScript.Sleep 3000

我还在记事本中使用以下代码在Backups.bat中创建了C:\Destination

@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime  ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%%MM%%DD%%HH%%Min%
rem Parameters set for use later


ZipCMD.vbs "C:\Source" "C:\Destination\BackupTest1.zip"
rem This line copies all files and folders from the Source to the Destination into a named .zip, without a date, by utilising the VBS created earlier.

Del "C:\Destination\*_BackupTest1.zip"
rem This line deletes the old backup (All **final** backups are named using 'YYYYMMDDhhmm_BackupTest1.zip'). The '_' prevents this command deleting the newly-created zip from before.

Rename C:\Destination\BackupTest1.zip %Stamp%_BackupTest1.zip
rem Renames newly-created zip file with datestamp and underscore (for information, and so that it can be identified for deletion next time this is run).

Set File="*_BackupTest1.zip"
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
rem These lines define a new parameter defined by the created .zip's size

Echo %stamp%%Sec%   %stamp%_BackupTest1.zip %Size%>>BackupLog.log
rem This last line appends a line to a log file containing the time the zip was created, the name of the .zip created, and its' size.

上述.bat的第二部分(在定义初始参数之后)可以针对多个文件夹重复,但每次都会更改“来源”。

最后,我在记事本中使用以下代码在RunBackups.vbs中创建C:\Destination

Set WshShell = CreateObject("WScript.Shell" ) 
WshShell.Run chr(34) & "C:\[SyncFolder]\Backups.bat" & Chr(34), 0 
Set WshShell = Nothing

这会运行.bat而不显示黑色CMD窗口(即以“静默”模式运行),并且是我使用任务计划程序自动执行备份过程时调用的文件。

问题: WScript.Sleep 3000中的ZipCMD.vbs行是一个混蛋。如果整个.zip文件可以在<3秒内创建,那很好。否则,我们有一个非功能性备份。扩展此计时器可能会导致更大或多个备份出现问题。

  • 解决方案尝试#1:在ZipCMD.vbs中,替换3000等待,启动一个循环,检查是否已使用name = ZipFile创建.zip。这会创建一个名称正确的.zip,但不包含任何数据(即备份进程已创建.zip,但vbs在有机会填充任何数据/文件之前已关闭)
  • 解决方案尝试#2:在ZipCMD.vbs中,替换3000等待,计算Source中的文件数,然后等待(循环)直到.zip包含该数量的文件,每次检查之间延迟500ms 。问题:这适用于除最后一个要复制的文件以外的所有文件。如果最后一个文件可以在&lt; 500ms内复制,则可行。否则,不会复制最后一个文件。对于包含非常大的文件的备份,扩展此计时器可能会出现问题。

问题:我可以用'替换'等待'计时器,以确保每次都完全创建.zip(不需要设置大量计时器),而不使用任何非默认值 - Windows功能? (即非第三方(例如7zip))

我听说过Java / Javascript(?)可能会解决这个问题,但我不确定这是怎么回事? (由于技术知识有限)

1 个答案:

答案 0 :(得分:1)

尝试修改后的ZipCMD.vbs

Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items

numfolderitems = objShell.NameSpace(InputFolder).Items.count

objShell.NameSpace(ZipFile).CopyHere(source)

' wait until number of items in zip file is the same as in the folder we are zipping up
' also sometimes gets errors when getting folder object for zip file, probably because it is in use? so ignore these
On Error Resume Next
Do while True
    numitemsinzip = objShell.NameSpace(ZipFile).Items.count
    If Err.Number = 0 and numitemsinzip = numfolderitems Then
        Exit Do
    ElseIf Err.Number <> 0 then
        Err.Clear
    End If
    wScript.Sleep 10
Loop
On Error Goto 0

这基本上是你的解决方案#2等待,直到zip文件中包含所有项目,除了我必须让它忽略它偶尔会得到的错误。我测试了几次,似乎工作正常。唯一可能的问题是如果由于某种原因导致压缩操作被停止,那么wscript.exe进程将永远运行,因为所有文件永远不会被放入zip文件中。