代码之家  ›  专栏  ›  技术社区  ›  M R

创建。使用VBS进行zip备份,无需硬编码等待计时器(Windows 7)[重复]

  •  1
  • M R  · 技术社区  · 7 年前

    我在填充创建的时遇到了一个问题。zip文件夹(用于备份 每件事 从…起 C:\Source 到a。拉链位于 C:\Destination ). 问题出现在 ZipCMD.vbs 文件我现在将描述我的整个过程,最后,我将用粗体字描述这个问题,以及我尝试(和失败)的解决方案。

    中存在一个包含测试数据的文件夹 C: \来源

    在里面 C: \目的地 创造 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: \目的地 在记事本中使用以下代码

    @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: \目的地 在记事本中使用以下代码

    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

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

    问题: 我可以用什么替换“等待”计时器,以确保。每次都会完全创建zip(不需要设置大量计时器),也不需要使用任何非默认的windows功能?(即非第三方(例如7zip))

    我听说Java/Javascript(?)可能会绕过这个问题,但我不确定这将如何/是否可行?(由于技术知识有限)

    1 回复  |  直到 7 年前
        1
  •  2
  •   garbb    7 年前

    试试这个改进的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文件中。