2017-11-21 12 views
0
나는 .ZIP 만든 폴더를 채우는 문제에 봉착

은 (C:\Destination에 위치한 .zip으로 C:\Source에서 모든 백업에 사용). 이 문제는 ZipCMD.vbs 파일에서 발생합니다. 내 모든 과정을 지금 설명하고 마지막에는 굵은 글씨로 문제와 내가 시도한 (및 실패한) 해결책을 설명하겠습니다.는 (윈도우 7) 하드 코딩 된 대기 타이머없이 VBS를 사용하여 .ZIP 백업을 만들기

은 (게르하르트 버나드에게 감사)

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을 만든 메모장에 다음 코드를 사용하여 ZipCMD.vbs를 작성, C:\Destination에서

C:\Source에, 테스트 데이터를 포함하는 폴더가 존재한다 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의 두 번째 섹션 (초기 매개 변수 정의 이후)은 여러 폴더에 대해 반복 될 수 있지만 매번 '소스'는 변경 될 수 있습니다.

마지막으로, 나는이 ('침묵'모드에서 실행 예) 나타나는 검은 CMD 창을없이 박쥐를 실행

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

메모장에 다음 코드를 사용하여 C:\DestinationRunBackups.vbs를 만들고있다 파일 작업 스케줄러를 사용하여 백업 프로세스를 자동화하도록 요청합니다.

문제 :WScript.Sleep 3000의 줄은 ZipCMD.vbs입니다. 전체 .zip 파일을 < 3 초 내에 만들 수 있다면 좋습니다. 그렇지 않으면 비 기능 백업이 있습니다. 이 타이머를 확장하면 대규모 또는 여러 백업에 문제가 발생할 수 있습니다.

  • 해결하려고 # 1 : ZipCMD.vbs에서, 대기 (3000)를 대체하는 .ZIP은 NAME = ZipFile를로 생성되었는지 여부를 검사하는 루프를 시작한다. 이렇게하면 올바른 이름의 .zip이 만들어 지지만 데이터가 없습니다 (즉, 백업 프로세스에서 .zip가 생성되었지만 데이터/파일을 채우기 전에 vbs가 닫힌 경우)
  • 솔루션 시도 # 2 : In ZipCMD.vbs은 3000 대기를 대체하고 소스의 파일 수를 계산하고 .zip에 해당 수의 파일이 포함될 때까지 대기합니다 (루프). 각 검사 사이에는 500ms의 지연이 있습니다. 문제 : 이것은 복사 할 마지막 파일을 제외한 모든 파일에 대해 완벽하게 작동합니다. 마지막 파일을 < 500ms에 복사 할 수 있으면이 방법이 효과적입니다. 그렇지 않으면 마지막 파일이 복사되지 않습니다. 이 타이머를 확장하면 매우 큰 파일을 포함하는 백업에 문제가 발생할 수 있습니다.

질문 : 나는 어떤 기본이 아닌-창 기능을 사용하지 않고 (다만 대규모 타이머를 설정하지 않고) 한 .zip 완전히 때마다 생성되는 것을 보장하기 위해 함께 타이머를 '대기'대체 할 수있는 무엇 ? (예 : 타사 (예 : 7zip))

Java/Javascript (?)가이 문제를 해결할 수 있다고 들었지만 어떻게 작동합니까? (제한된 기술적 지식으로 인해)

답변

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 

이 기본적으로 zip 파일 때까지 기다리는 솔루션 # 2 것은 내가 가끔 얻을 것이라고는 오류를 무시했습니다 제외하고 그것의 모든 항목이 있습니다. 나는 그것을 몇 번 시험해 보았고 그것은 잘 작동하는 것처럼 보인다. 유일한 잠재적 인 문제는 zip 작업이 어떤 이유로 중지되면 wscript.exe 프로세스가 모든 파일이 zip 파일에 절대 들어 가지 않기 때문에 영원히 실행되는 것입니다.

+0

이것은 실제로 효과가 있습니다! 그러나 더 큰 .zip 파일을 만들 때 압축 인터페이스가 나타납니다. 이 일이 일어나지 않는 방법이 있습니까? (즉, 압축 프로세스가 백그라운드에서 수행하기 위해?) –

+0

죄송합니다 [copyhere에 대한 문서를 (https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866 (V = VS.85) .aspx)에는 진행 대화 상자를 숨기는 플래그가 있지만 어떤 이유로 zip 파일에 대해 작동하지 않는 것으로 보입니다. – garbb

+0

충분합니다. 후속 질문 : 어떻게 든 .zip에 복사 된 파일의 수를 (.log 파일에서의 기록에 사용하기 위해) 계산할 수 있습니까? 예 : 'Set FileCount = CountOfFilesZipped' 그리고 나중에'Echo % FileCount %'- 만약 그렇다면 어떻게 구현합니까? - ** 생성 후 .zip 파일의 '개수'는이 목적으로 작동합니다 ** –