Archiv unter Windows 8 entpacken

8

Ich habe zuvor MiniZip (zlib wrapper) verwendet, um Archive zu entpacken. MiniZip kann nicht für Metro-Anwendungen verwendet werden, da veraltete APIs in "iowin32.c" - CreateFile () und SetFilePointer () verwendet werden.

Ich dachte, das wäre eine einfache Lösung und erstellt "iowinrt.c" mit CreateFile () und SetFilePointer () ersetzt durch CreateFile2 () und SetFilePointerEx (). Während ich auf diese Weise eine Version von MiniZip erhielt, die nur genehmigte Win8-APIs verwendet, erwies es sich immer noch als nutzlos - ich vergaß Sandboxing. Wenn ich mit FileOpenPicker () eine Datei auswähle und ihren Pfad an mein modifiziertes MiniZip übergebe, kann ich sie immer noch nicht öffnen - CreateFile2 () wird mit "Zugriff verweigert" fehlschlagen. Nachricht.

So scheint es, dass die alte C-API für den Dateizugriff jetzt größtenteils nutzlos ist; Es ist mein Verständnis, dass, um dies zu beheben, ich mein "iowinrt" in C ++ / CX mit dem neuen asynchronen Dateizugriff neu implementieren müsste. Gibt es noch andere Möglichkeiten? Ich glaube, ich habe irgendwo gesehen, dass WinRT Funktionen zum Komprimieren / Dekomprimieren hat, aber das funktioniert nur für einzelne Dateien, nicht für Archive.

Zusätzliche Anforderungen, die ich brauche, um im Speicher zu arbeiten.

Für einen Moment dachte ich, ich hätte eine Lösung über .NET Framework 4.5:

  1. Ich habe diese Information über das Erstellen von .NET-Klassen gefunden, die aus C ++ / CX verwendet werden können: Ссылка

  2. .NET Framework 4.5 enthält ZipArchive- und ZipArchiveEntry-Klassen in System.IO.Compression: Ссылка http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry%28v=vs.110%29.aspx#Y0

Ich dachte, ich könnte C # Metro-Klassenbibliothek mit WinMD-Ausgabetyp erstellen, die ZipArchive und ZipArchiveEntry freigibt, und dann diese in meinem C ++ / CX-Projekt verwenden. Aber selbst wenn es funktionierte, würde es nicht im Speicher funktionieren. anscheinend funktionieren ZipArchive und ZipArchiveEntry nur mit Dateien.

    
Galadrius Krunthar 07.06.2012, 06:30
quelle

1 Antwort

5

Habe aus dem Archiv gelesen. Erklärung und Code unten, aber eigentlich nur ein Hack an dieser Stelle, um zu sehen, ob es überhaupt möglich ist. Ich änderte nur die Dinge, bis etwas funktionierte. Dies ist nur ein Beispiel dafür, was funktioniert und auf keinen Fall einen Produktionsqualitätscode (es ist für den Anfang nicht einspringend). Es gibt zweifellos viele Dinge, die schlecht / unnötig / wtf sind, also fühlen Sie sich frei, Kommentare zu verwenden, um mit Aufräumen zu helfen.

Wie bereits erwähnt, reicht es nicht mehr aus, den Pfad zur Bibliothek zu übergeben - es sei denn, die Datei befindet sich in einem der bekannten Ordner (Dokumente, Zuhause, Medien, Musik, Bilder, Wechselmedien oder Videos) und "Zugriff verweigert" " Botschaft. Stattdessen muss die Bibliothek StorageFile ^, wie von FileOpenPicker zurückgegeben, akzeptieren können. Zumindest habe ich keine andere Möglichkeit gefunden, es zu tun, vielleicht weiß es jemand besser?

MiniZip bietet Windows-Dateisystem-Zugriffsebene für zlib über iowin32.h / .c. Dies funktioniert immer noch im Desktop-Modus für ältere Apps, funktioniert aber nicht für Metro-Apps, da veraltete APIs verwendet werden und Pfade verwendet werden. Um MiniZip unter Windows 8 laufen zu lassen, ist ein vollständiges Neuschreiben von iowin32 erforderlich.

Um die Dinge wieder in Gang zu bringen, musste zuerst eine Möglichkeit gefunden werden, StorageFile ^ bis nach iowinrt (Windows 8 Ersatz für iowin32) zu übergeben. Glücklicherweise war das kein Problem, da MiniZip zwei Arten von offenen Dateifunktionen bietet - solche, die den Zeiger auf das Zeichen akzeptieren, und die anderen, die den Zeiger auf void akzeptieren. Da ^ immer noch nur ein Zeiger ist, kann StorageFile ^ auf void * und dann wieder auf StorageFile ^ angewendet werden.

Nun, da ich StorageFile ^ an mein neues iowinrt übergeben konnte, war das nächste Problem, wie man neue asynchrone C ++ - Dateizugriffs-API mit Zlib arbeiten ließ. Um sehr alte C-Compiler zu unterstützen, wird Zlib mit dem alten K- und R-Stil C geschrieben. Der VisualStudio-Compiler weigert sich, dies als C ++ zu kompilieren, es muss als C kompiliert werden, und neues iowinrt muss natürlich als C ++ kompiliert werden - Berücksichtigen Sie dies bei der Erstellung Ihres Projekts. Andere Dinge zu VS Projekt zu beachten ist, dass ich es als Visual C ++ Windows Metro static Static Library gemacht, obwohl DLL sollte auch funktionieren, aber Sie müssen auch Makro zu MiniZip API exportieren (ich habe dies nicht versucht, weiß nicht, welches Makro du musst benutzen). Ich denke, ich musste auch "Verbraucht Windows Runtime Extension" (/ ZW) einstellen, setze "Keine vorkompilierten Header verwenden" und füge _CRT_SECURE_NO_WARNINGS und _CRT_NONSTDC_NO_WARNINGS Preprozessor-Definitionen hinzu.

Was iowinrt selbst betrifft, habe ich es in zwei Dateien aufgeteilt. Man hält zwei versiegelte Ref-Klassen - Reader- und Writer-Objekte; Sie akzeptieren StorageFile ^. Reader implementiert Read, Tell, SeekFromBeginning, SeekFromCurrent und SeekFromEnd (der Grund für 3 Seek-Methoden ist, dass ref sealed Klassen bei RT-Typen bleiben müssen und das anscheinend enums ausschließt, also habe ich einfach den einfachen Weg genommen). Writer implementiert gerade Write im Moment, habe es noch nicht benutzt.

Dies ist der FileReader-Code:

%Vor%

iowinrt befindet sich zwischen MiniZip und FileReader (und FileWriter). Es ist zu lang, um alles hier zu geben, aber dies sollte ausreichen, um den Rest zu rekonstruieren, da es meistens mehr von den gleichen Funktionsnamen ist, plus eine Reihe von fill_winRT_filefuncxxx (), die offensichtlich sind:

%Vor%

Dies ist genug, um MiniZip zum Laufen zu bringen (zumindest zum Lesen), aber Sie müssen aufpassen, wie Sie MiniZip-Funktionen aufrufen - da es bei Metro nur um Async geht und der blockierende UI-Thread mit einer Ausnahme endet, müssen Sie den Zugriff umbrechen Aufgaben:

%Vor%     
Galadrius Krunthar 14.06.2012 23:44
quelle

Tags und Links