ZIP Dateien automatisch unzipen und verschieben?

8 Antworten

Ich weiß nicht, ob das eigene Windows interne Zip auch ein CMD-Tool mitliefert, 7zip kann das aber auf jeden Fall.

Also lade 7zip runter muss nicht zwingend installiert sein, der Ordner reicht. Darin gibt's mehrere Programme, die "7zipFM.exe" ist das Programm mit Benutzeroberfläche, das willst Du nicht. Du brauchst die "7z.exe", die ist für die CMD gemacht.

Einfach mal in der CMD aufrufen, dann zeigt es dir mögliche Befehle an, oder Du suchst online nach der Doku dazu.

Und dann brauchst Du auch nichts verschieben, Du gibst einfach direkt den Pfad an, wo alles landen soll.


Palladin007  17.08.2021, 09:36

PS:

Das automatisch erkennen von neuen Dateien ist aber nicht so ohne Weiteres möglich, zumindest nicht mit Batch. C# hat den FileSystemWatcher, andere Sprachen haben andere Möglichkeiten.

Oder Du lässt dein Entpack-Skript regelmäßig von der Windows-Aufgabenverwaltung ausführen.

2

Ich hatte eben etwas Zeit und habe das ganze mal als klassische Batch mit JS-Hilfsscript realisiert.

Wie bereits im ersten Ansatz erwähnt ist das Ganze in punkto Resourcen ungünstig, da jedesmal das komplette Verzeichnis gescannt wird, statt auf ein Systemereignis zu warten.

@echo off
chcp 65001 >nul
set "SourceFolder=C:\zip"
set "DestinationFolder=C:\unzip"
set "ZipFileFolder=C:\downloads"
set "Delay=60" &rem  wartezeit in Sekunden (5 sekunden würden das System strapazieren!)


if not exist "%temp%\unzip2.js" echo args=WScript.Arguments;if (args.length^<1){WScript.Quit()};FSO=new ActiveXObject("Scripting.FileSystemObject");ShlApp = new ActiveXObject( "Shell.Application" );ZipFile=FSO.GetAbsolutePathName(args(0));if ((FSO.GetExtensionName(ZipFile))=='') {ZipFile=FSO.GetAbsolutePathName(ZipFile+'.zip')};if (!FSO.FileExists(ZipFile)){WScript.Quit()};OutFolder='.';if (args.length^>1){OutFolder=args(1)};OutFolder= FSO.GetAbsolutePathName(OutFolder);ShlApp.NameSpace(OutFolder).CopyHere(ShlApp.NameSpace(ZipFile).Items(),20) >"%temp%\unzip2.js"
md "%ZipFileFolder%" 2>nul
  rem Endlosloop
for /l %%i in (0) do (
      rem finde Zipfiles
    for /f "tokens=*" %%a in ('dir /b "%SourceFolder%\*.zip"') do (
       echo Datei "%%a" gefunden
       cscript //nologo "%temp%\unzip2.js" "%%~dpna" "%DestinationFolder%"
       move /y "%%a" "%ZipFileFolder%" >nul
)
timeout %Delay% >nul
)

das Hilfsscript wirkt nur Monströs, da ich es als Einzeiler generiere.

hübsch zeilenweise sähe es so aus:

unzip2.js

args=WScript.Arguments;
if (args.length<1){
    WScript.Echo ('Aufruf:\r\n'+WScript.ScriptName+' ZipFile[.zip] [OutputFolder]')
    WScript.Quit()
}
FSO=new ActiveXObject("Scripting.FileSystemObject")
ShlApp = new ActiveXObject( "Shell.Application" )
ZipFile=FSO.GetAbsolutePathName(args(0))
if ((FSO.GetExtensionName(ZipFile))=='') {ZipFile=FSO.GetAbsolutePathName(ZipFile+'.zip')}
if (!FSO.FileExists(ZipFile)){WScript.Echo (ZipFile+' nicht gefunden');WScript.Quit()}
OutFolder='.'
if (args.length>1){OutFolder=args(1)}
OutFolder= FSO.GetAbsolutePathName(OutFolder)
ShlApp.NameSpace(OutFolder).CopyHere(ShlApp.NameSpace(ZipFile).Items(),20) 


Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

Kompressionstools wie WinRAR oder 7zip bieten Parameter für die Kommandozeile, die das automatische Packen und Entpacken unterstützen.

Beispiel:

C:\Programm Files (x86)\WinRAR>WinRAR x "C:\tmp\xxx.zip" "C:\tmp"

Verschieben kannst du Dateien, indem du sie kopierst (copy) und anschließend die Quelldaten löschst (del).


Mit Batch eher nicht...

ist zwar mit jeder Menge Rödelei und resurcenfressendem Pollig machbar, aber nicht empfehlenswert. (...und schon garnicht mit 4 Zeilen)

...wenn es nicht C# sein soll lässt sich auch in Powershell mit den Filesystemwatcher arbeiten.

die Folgende Demo hat Netto ca. 20 Zeilen (ohne Kommentare etc.) und entpackt jedes neu im ordner c:\zip neu erzeugte zip nach Desktop.

zip_watch.ps1

$SourceFolder='C:\zip'
  #Achtung! aufgerufene Variablen und Funktionen innerhalb der Callbackfunktion (Scriptblock!) Global definieren
$global:DestinationFolder='C:\unziped'
function global:ExpandZip ($ZipFile,$DestinationPath) {
    #Expand-Archive
    Write-Host "mache was" $ZipFile $DestinationPath
    Expand-Archive $ZipFile $DestinationPath -force
}

  ### erzeuge  einen  Dateisystembeobachter
$watcher=New-Object System.IO.FileSystemWatcher
  #zu beobachtender Ordner 
$watcher.Path=$SourceFolder
  #Dateimaske, welche Dateien beobchtet werden sollen (hier  Zip)
$watcher.Filter='*.zip'
  #auch Unterverzeichnisse beobachten?
$watcher.IncludeSubdirectories=$false
$watcher.EnableRaisingEvents=$false 


### was soll getan werden  (scriptblock variable)
$action={
      # Rückgabe Datei, welche  das Ereignis ausgelöst  hat...
    $path = $Event.SourceEventArgs.FullPath
      #welche Veränderung der Auslöser  war
    $changeType = $Event.SourceEventArgs.ChangeType
      #etwas  anzeigen
    Write-Host "$path was $changetype at $(get-date)"
    ExpandZip $Event.SourceEventArgs.FullPath $global:DestinationFolder
}
    
### registriere  Ereignisse, auf welche wie reagiert werden soll 
  #du  kannst  natürlich für jedes Ereignis auch  eine  eigene Actionvariable definieren
  #...oder einfach nur  das Ereignis  registrieren, auf welches Du reagieren möchtest
Register-ObjectEvent $watcher "Created" -Action $action|Out-Null
  #Reaktion auf andere Ereignisse für diese Demo deaktiviert
#Register-ObjectEvent $watcher "Changed" -Action $action|Out-Null
#Register-ObjectEvent $watcher "Deleted" -Action $action|Out-Null
#Register-ObjectEvent $watcher "Renamed" -Action $action|Out-Null

  #Endlosschleife. Welche das Script geöffnet hält, Reaktionszeit auf  Eereignisse hier 5 sekunden(kann auch länger oder Kürzer)
while ($true) {
    Write-Host '.' -n;
    sleep 5
}

Was das laufen im Hintergrund betrifft , sollte es kein Problem sein das Fenster zu minimieren. Das ist ein administratives Script und soll automatiesiern und keinen Schönheitspreis gewinnen🙄. Schließlich muss man als Administrator auch eingreifen können...

Natürlich könnte man das Powerschellscript auch noch in einer Hybridbatch unterbringen .

Wie das geht habe ich schon zig mal zelebriert:

zb. https://www.gutefrage.net/frage/powershell-skript-automatisch-ausfuehren#answer-394285184

oder in der Rubrik batch-trick

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

Erzesel  17.08.2021, 12:50

ps hier noch mit "wegschieben der Zip-datei:

$SourceFolder='C:\zip\'  #ordner  der überwacht werden soll
$global:DestinationFolder='C:\unzip'   #wohin entpackt werden soll
$global:ZipFileFolder='C:\downloads\'  #wohin das entpackte zip verschoben werden soll
function global:ExpandZip ($ZipFile,$DestinationPath) {
    Expand-Archive $ZipFile $DestinationPath -force   #zipdatei entpacken
    Move-Item $ZipFile -Destination $global:ZipFileFolder -force  #zipdatei verschieben
}

New-Item $global:ZipFileFolder -ItemType "directory" -force >$null  #Erzeuge, wenn noch nicht  existent

$watcher=New-Object System.IO.FileSystemWatcher
$watcher.Path=$SourceFolder
$watcher.Filter='*.zip'
$watcher.IncludeSubdirectories=$false
$watcher.EnableRaisingEvents=$false 

$action={
    $path = $Event.SourceEventArgs.FullPath
    $changeType = $Event.SourceEventArgs.ChangeType
    Write-Host "$path was $changetype at $(get-date)"
    ExpandZip $Event.SourceEventArgs.FullPath $global:DestinationFolder
}
    
Register-ObjectEvent $watcher "Created" -Action $action|Out-Null
while ($true) {sleep 5}
0

Sollte kein grosses Problem sein.

Du installierst z.B. 7zip und hast damit auch die Kommandozeilenversion 7z.exe zum Entpacken.
Verschieben kannst Du mit move, ggfls auch mit kopieren/löschen (z.B. mit rsync oder robocopy).
Das Ganze packst Du in eine kleine Batchdatei, die wird nur wenige Zeilen haben.
Aufgerufen wird das über den Taskplaner , noch schicker geht es mit dem bereits erwähnten Z-Cron.

Alternativ kannst Du natürlich jederzeit das Linux-Subsystem von Windows 10 aktivieren und das mit einem ShellScript lösen, eine weitere Alternative wäre cygwin oder nur die bash davon.

https://helpdeskgeek.com/free-tools-review/5-best-windows-task-scheduler-alternatives/