Problem mit der Funktion "SmartZip"

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

Problem mit der Funktion "SmartZip"

04 Aug 2017, 03:43

Huhu zusammen,

ich benutze folgende Funktion(en), um ZIP Archive zu erstellen:

Code: Select all

; ###################################################
; ##########           SmartZip            ##########
; ###################################################

; S = Quelldatei(en)
; o = Zieldatei (ZIP)
; t = Optionen (http://msdn.microsoft.com/en-us/library/windows/desktop/bb787866)
;   4    = Do not display a progress dialog box.
;   8    = Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.
;   16   = Respond with "Yes to All" for any dialog box that is displayed.
;   64   = Preserve undo information, if possible.
;   128  = Perform the operation on files only if a wildcard file name (*.*) is specified.
;   256  = Display a progress dialog box but do not show the file names.
;   512  = Do not confirm the creation of a new directory if the operation requires one to be created.
;   1024 = Do not display a user interface if an error occurs.
;   2048 = Version 4.71. Do not copy the security attributes of the file.
;   4096 = Only operate in the local directory. Do not operate recursively into subdirectories.
;   8192 = Version 5.0. Do not copy connected files as a group. Only copy the specified files.

SmartZip(s, o, t = 1808)
{
    IfNotExist, %s%
        return, -1

    oShell := ComObjCreate("Shell.Application")

    if (SubStr(o, -3) = ".zip")
    {
        IfNotExist, %o%
            CreateZip(o)
        
        Loop, %o%, 1
            sObjectLongName := A_LoopFileLongPath

        oObject := oShell.NameSpace(sObjectLongName)

        Loop, %s%, 1
        {
            if (sObjectLongName = A_LoopFileLongPath)
                continue

            GuiControl, Main: , SBAR, Komprimiere Ordner '%A_LoopFileName%'...
            oObject.CopyHere(A_LoopFileLongPath, t)
            SplitPath, A_LoopFileLongPath, OutFileName
            If InStr(OutFileName, "System Volume Information")
                continue

            Loop
            {
                oObject := ""
                oObject := oShell.NameSpace(sObjectLongName)
                if oObject.ParseName(OutFileName)
                    break
            }
        }
    }

    else if (InStr(FileExist(o), "D") or (!FileExist(o)) and (SubStr(s, -3) = ".zip"))    ; Unzip
    {
        if !o
            o := A_Desktop

        else IfNotExist, %o%
            FileCreateDir, %o%

        Loop, %o%, 1
            sObjectLongName := A_LoopFileLongPath
        
        oObject := oShell.NameSpace(sObjectLongName)
        
        Loop, %s%, 1
        {
            oSource := oShell.NameSpace(A_LoopFileLongPath)
            oObject.CopyHere(oSource.Items, t)
        }
    }
}

CreateZip(n)    ; Leere ZIP Datei erzeugen
{
    ZIPHeader1 := "PK" . Chr(5) . Chr(6)
    VarSetCapacity(ZIPHeader2, 18, 0)
    ZIPFile := FileOpen(n, "w")
    ZIPFile.Write(ZIPHeader1)
    ZIPFile.RawWrite(ZIPHeader2, 18)
    ZIPFile.close()
}



; ###################################################
; ##########             UnZip             ##########
; ###################################################

Extract2Folder(Zip, Dest="", Filename="")
{
    SplitPath, Zip,, SourceFolder
    if ! SourceFolder
        Zip := A_ScriptDir . "\" . Zip
    
    if ! Dest {
        SplitPath, Zip,, DestFolder,, Dest
        Dest := DestFolder . "\" . Dest . "\"
    }
    if SubStr(Dest, 0, 1) <> "\"
        Dest .= "\"
    SplitPath, Dest,,,,,DestDrive
    if ! DestDrive
        Dest := A_ScriptDir . "\" . Dest
    
    fso := ComObjCreate("Scripting.FileSystemObject")
    If Not fso.FolderExists(Dest)  ;http://www.autohotkey.com/forum/viewtopic.php?p=402574
       fso.CreateFolder(Dest)
       
    AppObj := ComObjCreate("Shell.Application")
    FolderObj := AppObj.Namespace(Zip)
    if Filename {
        FileObj := FolderObj.ParseName(Filename)
        AppObj.Namespace(Dest).CopyHere(FileObj, 4|16)
    }
    else
    {
        FolderItemsObj := FolderObj.Items()
        AppObj.Namespace(Dest).CopyHere(FolderItemsObj, 4|16)
    }
}
So weit funktioniert alles prima, bis auf einen kleinen Schönheitsfehler:

Ich benutze die Routine, um eine SD Karte komplett als ZIP Archiv zu sichern.
Immer wieder bekomme ich den Fehler, den ich unten angehängt habe.
Ich vermute, dass dies auf leere Ordner zurückzuführen ist, die sich auf der
SD Karte befinden.

Merkwürdigerweise kommt dieser Fehler bei der selben SD Karte mit selbem Inhalt nicht immer (ca. 50:50).
Kann mir dazu jemand einen Rat geben?
Ich vermute, dass dieser Fehler durch leere Ordner ausgelöst wird, die sich auf der SD Karte befinden, sicher kann ich dies jedoch nicht sagen.

Sollte meine Vermutung stimmen, wie kann ich den Fehler umgehen?
Ich habe bei den Parametern dutzende Varianten ausprobiert, bin aber bisher zu keinem Ergebnis gekommen. Prinzipiell würde es reichen, wenn die Fehlermeldung selbst unterdrückt werden könnte, da
die ZIP Archive alle (ob mit oder ohne diese Meldung) vollständig und fehlerfrei sind. Auch leere Ordner erscheinen darin.

Lieben Dank für Eure Ideen/Ratschläge im Voraus,

Gucky.
Attachments
Unbenannt.png
Unbenannt.png (3.98 KiB) Viewed 1139 times
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Problem mit der Funktion "SmartZip"

04 Aug 2017, 06:42

Interessant wäre hier vll noch dein funktionsaufruf gewesen, da die genannten optionen ja entsprechend aufaddierbar sind ...
User avatar
Gucky_87
Posts: 375
Joined: 03 Jul 2014, 05:09

Re: Problem mit der Funktion "SmartZip"

05 Aug 2017, 10:55

Huhu.

Ich schrieb ja, dass ich dutzende Varianten ausprobiert habe und KEINE diesen Fehler umgehen konnte.
Auch ist merkwürdig, dass wenn ich die Optionen 4 und 1024 setze, mir trotzdem ein Fortschrittsfenster angezeigt wird. Ok, das ist nicht schlimm und passt auch irgendwie, da man sieht, was der Rechner gerade macht.

Aktuell verwende ich folgende n Aufruf: SmartZip(ORDNER, FOLDER_COPY_PATH, 1808)
Die Variaben werde korrekt übergeben, denn die ZIP Datei wird ja letztendlich korrekt geschrieben und sie ist fehlerfrei und enthält auch leere Unterordner.

Insbesondere aber die Option 1024 (Do not display a user interface if an error occurs.) sollte ja bewirken, was ich oben schrieb. Es sollten keinerlei Fehlermeldungen angezeigt werden.
Genau das aber passiert leider nicht.

Ich überlege nun schon, ob ich einen schnellen Timer einbaue, den ich VOR dem Aufruf der Routine starte und der die Fehlermeldung einfach "kickt", sobald sie auftaucht. Das wäre zwar die "Quick´n Dirty" Methode, aber was habe ich für eine Wahl?

Gruß,

Gucky.
just me
Posts: 9450
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Problem mit der Funktion "SmartZip"

07 Aug 2017, 02:36

https://msdn.microsoft.com/en-us/librar ... p/bb787866
MSDN wrote:vOptions [optional]
...
Note In some cases, such as compressed (.zip) files, some option flags may be ignored by design.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 45 guests