Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Unzip mit der Shell32 (https://www.delphipraxis.net/179701-unzip-mit-der-shell32.html)

Gerd01 25. Mär 2014 16:19

Unzip mit der Shell32
 
Es gibt eine elegante Mögichkeit mit der Shell32 ein Zipfile zu entpacken. Mein Quelltext hierfür ist dieser:

Delphi-Quellcode:
const
  SHCONTCH_NOPROGRESSBOX = 4;
  SHCONTCH_AUTORENAME = 8;
  SHCONTCH_RESPONDYESTOALL = 16;
  SHCONTF_INCLUDEHIDDEN = 128;
  SHCONTF_FOLDERS = 32;
  SHCONTF_NONFOLDERS = 64;
 
function ShellUnzip(zipfile, targetfolder: string; filter: string = '*.*'): boolean;
var
  shellobj: olevariant;
  srcfldr, destfldr: olevariant;
  shellfldritems: olevariant;
  FilterV,
  ZipFileV, TargetFldrV: Variant;
begin
  shellobj := CreateOleObject('Shell.Application');

  /// 25.03.2014 17:07 -> Keine direkte Zuweisung von ZipFile an shellobj.NameSpace(...
  ZipFileV := ZipFile;
  srcfldr := shellobj.NameSpace(zipfileV);

  /// 25.03.2014 17:07 -> dito
  TargetFldrV := targetfolder;
  destfldr := shellobj.NameSpace(TargetFldrV);
  shellfldritems := srcfldr.Items;

  /// 25.03.2014 17:07 -> dito
  FilterV := Filter;
  if (filter <> '') then
    shellfldritems.Filter(SHCONTF_INCLUDEHIDDEN or SHCONTF_NONFOLDERS,filterV);

  destfldr.CopyHere(shellfldritems,SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
end;
Nun aber mein Problem. Die zu entpackende files in der ZIP sind mit vollständigen Pfad gepackt. Wenn ich also die zip entpacke sind die entpackten Dateien nicht direkt im Zielordner sondern mit Pfad im Zielordner abgespeichert.

Gibt es eine Option oder Möglichkeit die Pfadangaben in den gepackten auszublenden, sodass ich die reinen Dateien im Zielordner habe?

himitsu 25. Mär 2014 16:27

AW: Unzip mit der Shell32
 
Man könnte natürlich mal auf eine total verrückt Idee kommen und in die Dokumentation schauen. :stupid:
http://msdn.microsoft.com/en-us/libr.../bb787866.aspx

Und nein.
Zitat:

Zitat von siehe Abschnitt in der Doku
Note In some cases, such as compressed (.zip) files, some option flags may be ignored by design.

Oder ja, wenn du dann nochmal umkopierst.




Zitat:

Keine direkte Zuweisung ...
Warum eigentlich?

Und wo wird das Result gesetzt?

Gerd01 26. Mär 2014 07:34

AW: Unzip mit der Shell32
 
Vielen Dank für den Hinweis auf die Dokumentation, da hatte ich allerdings schon nachgelesen.

Diese Hinweise mit zum Beispiel folgender Bemerkung:
Zitat:

Man könnte natürlich mal auf eine total verrückt Idee kommen und in die Dokumentation schauen
Einfach nur der Hinweis reicht.

Eine NameSpace mit einem string-Typ crasht, es wird ein varianter Typ erwartet.

Um umkopieren zu können, müsste ich die Inhalte (Dateien) der ZIP kennen. Hast jemand eine Idee?

himitsu 26. Mär 2014 08:14

AW: Unzip mit der Shell32
 
Den ZIP-Inhalt inkl. Unterverzeichnisse rauskopieren (eventuell in ein Temp-Verzeipchnis) und von da dann ohne Verzeichnisstruktur ins Zielverzeichnis, wofür es ja scheinbar eine Option gibt.

Oder du listest über srcfldr die Dateien und Verzeichnisse auf und kopierst Dateien einzeln, bzw. jeweils alle Dateien der Vereichnisse (ohne Unterverzeichne).
Wie, sollte in der Doku stehen, denn das weiß ich nun auch nicht.

Zitat:

Zitat von Gerd01 (Beitrag 1253532)
Vielen Dank für den Hinweis auf die Dokumentation, da hatte ich allerdings schon nachgelesen.

Wenn das CopyHere für ZIPs das nunmal nicht direkt bietet, dann geht es einfach nicht.
Aber das hätte man ja sehen können, wo es doch ganz deutlich in der Doku erwähnt wird.

Und ansonsten kann man immernoch eine der vielen ZIP-Komponenten verwenden, die es auch noch gibt.

Gerd01 28. Mär 2014 10:25

AW: Unzip mit der Shell32
 
Für den, den es interssiert, hier nochmal der Code mit der Übergabe der entpackten Dateiliste incl. Verzeichnisangabe:

Code:
const
  SHCONTCH_NOPROGRESSBOX = 4;
  SHCONTCH_AUTORENAME = 8;
  SHCONTCH_RESPONDYESTOALL = 16;
  SHCONTF_INCLUDEHIDDEN = 128;
  SHCONTF_FOLDERS = 32;
  SHCONTF_NONFOLDERS = 64;

function ShellUnzip(zipfile, targetfolder: string; FileList : TStringList; Const filter: string = ''): boolean;
var
  shellobj: olevariant;
  srcfldr, destfldr: olevariant;
  shellfldritems: olevariant;
  FilterV,
  ZipFileV, TargetFldrV: OleVariant;
  I:Integer;
begin
  shellobj := CreateOleObject('Shell.Application');

  /// 25.03.2014 17:07 -> Keine direkte Zuweisung von ZipFile an shellobj.NameSpace(...
  ZipFileV      := ZipFile;
  srcfldr       := shellobj.NameSpace(zipfileV);

  /// 25.03.2014 17:07 -> dito
  ForceDirectories(PChar(targetfolder));
  TargetFldrV   := targetfolder;
  destfldr      := shellobj.NameSpace(TargetFldrV);
  shellfldritems := srcfldr.Items;

  /// 25.03.2014 17:07 -> dito
  FilterV := Filter;
  if (filter <> '') then
    shellfldritems.Filter(SHCONTF_INCLUDEHIDDEN or SHCONTF_NONFOLDERS,filterV);

  destfldr.CopyHere(shellfldritems,SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);

  if Assigned(FileList) then
  Begin
    FileList.Clear;
    for I := 0 to shellfldritems.Count -1 do
      FileList.Add(shellfldritems.item(I).path);
  end;
end;

Schwedenbitter 19. Nov 2014 12:14

AW: Unzip mit der Shell32
 
Hallo,

dem Code lässt sich entnehmen, dass man mit
Zitat:

Zitat von Gerd01 (Beitrag 1253773)
Code:
...
      FileList.Add(shellfldritems.item(I).path);

auf die einzelnen Items (= Dateien) zumindest "lesend" zugreifen kann.

Gibt es eine Möglichkeit, dem zip-Entpacker mitzugeben, welche Dateien er entpacken soll?

Das geht zwar wohl vom Ansatz her mit Filter. Aber ich möchte z.B. die 3. und 26. Datei entpacken und die heißen z.B. "abc.de" und "fghi.jklm". Die Dateien einzeln auszupacken, dauert mir zu lang, weil allein schon das Öffnen des Shell-Fensters Ewigkeiten braucht. Es muss irgendwie funktionieren, weil es Windows selbst auch kann (wenn ich die Datei als Folder öffne, 2 Dateien markiere und auf entpacken klicke oder woanders hin kopiere...).
Wo kann man/ich dazu etwas finden?

[edit]
Man kann das meines Erachtens eleganter machen über das Casten. Also statt
Delphi-Quellcode:
 /// 25.03.2014 17:07 -> Keine direkte Zuweisung von ZipFile an shellobj.NameSpace(...
  ZipFileV     := ZipFile;
  srcfldr      := shellobj.NameSpace(zipfileV);
z.B.
Delphi-Quellcode:
  srcfldr      := shellobj.NameSpace(OleVariant(zipfile));
[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz