element23
Goto Top

Dateien per Batch über WinZip sichern

Hallo zusammen,

ich habe mich seit kurzem mit Scripting beschäftigt und möchte nun einen lästigen Vorgang über ein Script beschleunigen, dazu reichen nur leider meine Erfahrungen/Kenntnisse nicht aus.
Situation:
Ich habe verschiedene Dateien die ein Programm erzeugt, möchte diese per Script mit WinZip sichern lassen.
Die Daten sollten nach Monaten/Jahren sortiert zusammen gepackt gezipt werden und dann auch beispielsweise 201106.zip heißen und nach Erfolg gelöscht werden.
Mein Problem ist, das ich die Variablen leider nicht kenne bzw. nicht so recht den Aufbau auf die Reihe bekomme.

Hier mein Anfang:

"@echo

C:\Backup\

if not exist C:\Backup goto fehler
if exist C:\Backup next

:next
C:\Programme\WinZip\wzzip -es "C:\Backup\Backup.zip" "C:\Backup\"

exit"

Ich würde mich über Tipps/Vorschläge/Lösungen etc. sehr freuen

Mit freundlichen Grüßen
Element

Content-ID: 169503

Url: https://administrator.de/contentid/169503

Ausgedruckt am: 26.11.2024 um 07:11 Uhr

Snowman25
Snowman25 11.07.2011 um 17:58:56 Uhr
Goto Top
Darf ich fragen, warum du den Beitrag auf gelöst gesetzt hast?
Friemler
Friemler 11.07.2011 um 18:25:36 Uhr
Goto Top
Das würde mich auch interessieren. Ich hatte gerade ein Script fertig...

[EDIT]
Ich poste das Script dennoch, falls jemand anderes diesen Thread mal über die SuFu findet:
@echo off & setlocal


set "SrcDir=C:\Backup"  
set "DestDir=%SrcDir%_Zipped"  


md "%DestDir%" 2>NUL  

set "VBScript=%Temp%\GetFilesAndDate.vbs"  

> "%VBScript%" echo Set objFSO = CreateObject("Scripting.FileSystemObject")  
>>"%VBScript%" echo For Each objFile In objFSO.GetFolder(WScript.Arguments(0)).Files  
>>"%VBScript%" echo   WScript.Echo Year(objFile.DateCreated) ^& Right("0" ^& Month(objFile.DateCreated), 2) ^& ":" ^& objFile.Path  
>>"%VBScript%" echo Next  

set "LastDate="  
set "FileList="  

for /f "tokens=1* delims=:" %%a in ('cscript /nologo "%VBScript%" "%SrcDir%" ^| sort') do (  
  call :ProcessFile %%a "%%b"  
)

call :ProcessFile 0
del "%VBScript%"  

exit /b



:ProcessFile
  if "%1" neq "%LastDate%" (  
    if defined FileList (
      "C:\Program Files\WinZip\wzip.exe" -es "%DestDir%\%LastDate%.zip" %FileList%  
      for %%f in (%FileList%) do del "%%~f"  
    )
    set "LastDate=%1"  
    set "FileList=%2"  
  ) else (
    set "FileList=%FileList% %2"  
  )
exit /b

In den Zeilen 12 bis 15 wird ein temporäres VBScript erzeugt, das als Parameter den Pfad zu einem Verzeichnis erwartet. Das Script ermittelt alle Dateien dieses Verzeichnisses und gibt ihren vollständigen Pfad sowie das Jahr und den Monat des Erstellungsdatums in folgendem Format aus:
JJJJMM:Laufwerk:\Pfad\Dateiname.Erweiterung
Im Kopf der FOR-Schleife in den Zeilen 20 bis 22 wird das VBScript ausgeführt und seine Ausgabe über eine Pipeline an SORT geschickt. Dessen Ausgabe ergibt also eine nach Datum sortierte Liste aller Dateien des Verzeichnisses. Die FOR-Schleife zerlegt diese Ausgabe in die Datums- und die Pfadkomponente und ruft für jede Datei das Unterprogramm ProcessFile auf. Als erster Parameter wird die Datumskomponente und als zweiter Parameter die Pfadkomponente übergeben.

Das Unterprogramm ProcessFile prüft, ob das übergebene Datum (Parameter %1) vom Datum des letzten Aufrufs verschieden ist.
Wenn nicht, wird der übergebene Pfad (Parameter %2) an eine Liste von Dateipfaden angehängt (Zeile 40).
Wenn ja, werden in Zeile 34 alle Dateien aus der Dateiliste mit WinZip gepackt und danach in Zeile 35 die Quelldateien gelöscht.
Danach wird das aktuelle Datum gespeichert und die Dateiliste mit dem aktuellen Dateinamen als einzigem Eintrag überschrieben (Zeilen 37 u. 38).

Die Abfrage in Zeile 33 ist für den ersten Aufruf von ProcessFile relevant. Dann ist der aktuelle Datumswert vom verherigen/initialen Datumswert verschieden aber die Dateiliste ist natürlich noch leer.

Nach Abschluss der FOR-Schleife wird in Zeile 24 ProcessFile nochmals aufgerufen, um die zuletzt in die Dateiliste aufgenommenen Dateien zu verarbeiten. Als erster Parameter wird dann 0 übergeben, damit der Vergleich in Zeile 32 auf jeden Fall Wahr als Ergebnis liefert.

Das Parameterformat von WinZip ist mir nicht bekannt. Deshalb weiß ich nicht, ob man einfach eine Liste von Dateinamen an WinZip übergeben kann, so wie in Zeile 34. Evtl. muss hier noch eine Anpassung gemacht werden (z.B. die Dateipfade statt in eine Variable in eine Datei schreiben, wenn WinZip eine solche Dateiliste verarbeiten kann).

Gruß
Friemler
[/EDIT]
Element23
Element23 12.07.2011 um 09:43:27 Uhr
Goto Top
Element23
Element23 12.07.2011 um 15:47:33 Uhr
Goto Top
Hallo zusammen,
zuerst einmal vielen Dank Friemler, das Script konnte ich gut anpassen und bis auf ein größeres Problem hat es super geklappt.
Hier nun mein Problem bzw. Frage:
Gibt es eine Möglichkeit auf die WinZip/Winrar Archivierung zu verzichten und über eine .net Variante oder eine andere zu zippen?


Vielen Dank
Gruß
Element
Friemler
Friemler 12.07.2011 um 16:40:39 Uhr
Goto Top
Hallo Element23,

wenn Du damit ein anderes Archivierungsprogramm meinst - 7Zip. Kost' nix und gibt es als Konsolenversion.

Über .Net zippen - k.A. ob/wie das geht face-sad . Google ist Dein Freund.

Gruß
Friemler
Element23
Element23 13.07.2011 um 15:20:20 Uhr
Goto Top
Hallo Friemler,

über 7-Zip funktioniert das Archivieren auch wunderbar, mein Problem ist nur leider immer noch wie oben beschrieben, das ich gern meine Daten nach Pfad/Datum.zip erstellt haben möchte.
Da wollte ich wieder auf dein Script zurückgreifen und dies anpassen.
Problem meinerseits ist nur leider, das ich nicht so ganz verstehe wie der bzw. ein VBScript Aufruf funktioniert, beim starten des Scripts erstellt sich "ein" Ordner, wie auch im "DestDir=" angegeben ist.
Die Syntax des Programms kann ich nachvollziehen nur leider nicht so ganz warum es nicht funktioniert bzw. den aufruf des VBScripts ob dieser überhaupt so funktionieren kann?

Das Script schaut jetzt nach meinem versuch es auf 7-Zip anzupassen wie folgt aus:

@echo off & setlocal


set "SrcDir=C:\Backup\Sout\"
set "DestDir=%SrcDir%_Zipped"


md "%DestDir%" 2>NUL

set "VBScript=%Temp%\GetFilesAndDate.vbs"

"%VBScript%" echo Set objFSO = CreateObject("Scripting.FileSystemObject")
"%VBScript%" echo For Each objFile In objFSO.GetFolder(WScript.Arguments(0)).Files
"%VBScript%" echo WScript.Echo Year(objFile.DateCreated) ^& Right("0" ^& Month(objFile.DateCreated), 2) ^& ":" ^& objFile.Path
"%VBScript%" echo Next

set "LastDate="
set "FileList="

for /f "tokens=1* delims=:" %%a in ('cscript /nologo "%VBScript%" "%SrcDir%" ^| sort') do (
call :ProcessFile %%a "%%b"
)

call :ProcessFile 0
del "%VBScript%"

exit /b


:ProcessFile
if "%1" neq "%LastDate%" (
if defined FileList (
"C:\Programme\7-Zip" a -tzip "%DestDir%\%LastDate%.zip" %FileList%
for %%f in (%FileList%) do del "%%~f"
)
set "LastDate=%1"
set "FileList=%2"
) else (
set "FileList=%FileList% %2"
)
exit /b

pause


Ich weiß leider nicht ob das vbscript bzw. der untere Teil überhaupt angesprochen werden.
Evtl. weiß jemand eine Lösung bzw. kann meinem Verständnis auf die Sprünge helfen.

Viele Grüße
Element
Friemler
Friemler 13.07.2011 um 16:06:30 Uhr
Goto Top
Hallo Element,

zunächst mal ein paar Tipps:

  1. Wenn Du Programmcode postest, verwende bitte die . Das vermeidet, dass, so wie oben, eine Codezeile plötzlich in einer Textbox erscheint, Einrückungen verloren gehen u.ä. Dinge, die das Lesen des Quelltextes erschweren. Du kannst die Codeformatierung auch nachträglich einfügen face-wink .
  2. Statt set "SrcDir=C:\Backup\Sout\" würde ich set "SrcDir=C:\Backup\Sout" schreiben, sonst entsteht als Ausgabeverzeichnis C:\Backup\Sout\_Zipped. C:\Backup\Sout_Zipped wäre aber sinniger.
  3. Statt "C:\Programme\7-Zip" müsste es wohl eher "C:\Programme\7-Zip\7za.exe" heißen, wenn Du die Konsolenversion von 7Zip benutzt und diese nach C:\Programme\7-Zip kopiert hast.
  4. Dein PAUSE-Befehl in der letzten Zeile lässt mich folgendes vermuten:
    • Du startest das Script per Doppelklick und wolltest verhindern, dass sich das Konsolenfenster schließt. Beim debuggen von Batchscripts solltest Du das Script aber immer aus einem Konsolenfenster heraus starten und @echo OFF rausnehmen aber nicht SETLOCAL.
    • Du hast nicht verstanden, dass es sich bei dem Abschnitt unterhalb von :ProcessFile um ein Unterprogramm handelt. Das zweite EXIT /B in der letzten Scriptzeile stellt nicht das Ende des Programms dar, sondern ist der Rücksprungbefehl zum Hauptprogramm. Das Script endet nach dem ersten EXIT /B in Zeile 27. Wenn es fehlen würde, würde CMD einfach anfangen, den Code des Unterprogramms ProcessFile auszuführen. => Dein PAUSE muss vor das EXIT /B aus Zeile 27.

Wenn Du prüfen willst, ob ProcessFile ausgeführt wird, setze doch ein ECHO Hier ist ProcessFile als ersten Befehl in das Unterprogramm. Besser ist, wie schon gesagt, das Script ohne @echo OFF auszuführen, dann siehst Du alle Codezeilen in der Reihenfolge, in der sie ausgeführt werden. Um die Sache abzukürzen, würde ich dann nur 3 oder 4 Dateien in das Verzeichnis C:\Backup\Sout legen.

Der VBScript-Schnipsel wird in eine temporäre Datei geschrieben und durch CSCRIPT /NOLOGO ... im Kopf der FOR-Schleife ausgeführt. Die Ausgabe des Schnipsels wird von der FOR-Schleife in ihre Bestandteile zerlegt, die dann an die Laufvariablen %%a und %%b zugewiesen werden. FOR ist ein komplexer Befehl. Jedesmal zu erklären, wie das ganze funktioniert ist zu viel Aufwand, deshalb habe ich mein Tutorial zur FOR-Schleife geschrieben. Beschäftige Dich dort mit den Kapiteln "Allgemeines zur FOR-Schleife", "Die Mehrzweck-Variante, FOR /F" bzw. dessen Unterkapitel "Allgemeines zu FOR /F" und "Verarbeiten der Ausgabe eines Programms/Befehls"

Gruß
Friemler