Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ... (https://www.delphipraxis.net/212962-d7zip-sevenzip-pas-von-mail2nnv-fragen-zur-funktionsweise-dictionarysize.html)

DieDolly 29. Apr 2023 09:12


d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ...
 
Ich gehe gerade weg von JclCompression hin zu einem anderen ebenfalls kostenlosen Wrapper für die 7z.dll.
Dabei ist der aktuellsten den ich finden kann ein Fork vom originalen d7zip von mail2nnv https://github.com/mail2nnv/d7zip

Ich habe den ein wenig angepasst
- AddBk ist weg es gibt jetzt nur noch den SysUtils-Aufruf IncludeTrailingPathDelimiter
- ForceDirectories auch weg, nur noch SysUtils direkt
- SetDateTimeFile wurde durch TFile.SetCreationTime() ersetzt
- LZMA habe ich aus TZipCompressionMethod entfernt, da das scheinbar inkompatibel ist?

Das funktioniert soweit ganz gut. Aber ich habe noch keine Ahnung, was für Werte bei SetDictionarySize einzufügen sind. Bei 7z ist 63 die Obergrenze, bei Zip 32. Alles andere knallt.

Hier mein erster Versuch der funktioniert. Das ist jetzt nur alles reingeschrieben, keine Benutzeroberfläche (nur ein Button und eine ProgressBar). Es geht nur um den Test.
Wie funktioniet das mit der Wörterbuchgröße? In dieser Dokumentation wird von ganz anderen Werten gesprochen https://sevenzip.osdn.jp/chm/cmdline...DictionarySize

Was ich auch nicht verstehe:
- Kompressionsverfahren ist Copy, Kompressionsstärke 0 (Speichern). Wenn ich bei 7z die sonstigen Optionen auslassen, wird das Archiv auch nicht komprimiert. Schalte ich aber Multithreading dazu, wird es trotzdem komprimiert
- schalte ich alle Optionen ab und nur SetDictionnarySize() an, gibt es einen Fehler bei der Bereichsprüfung. Setze ich den Wert einfach mal auf 1, geht es. Aber woher soll ich das Maximum wissen?
Verwende ich das falsch?

Delphi-Quellcode:
function ProgressCallback(Sender: Pointer; Total: Boolean; Value: Int64): HRESULT; stdcall;
begin
 BytesCopied := Value; // Test

 if Total then
  Form1.ProgressBar1.Max := 100
 else
  Form1.ProgressBar1.Position := GetPercent(BytesToCopy, BytesCopied);

 Result := S_OK;
end;

function CompressionStrength(cs: TCompressStrength): Cardinal;
begin
 case cs of
  SAVE:
   Result := 0;
  FASTEST:
   Result := 1;
  FAST:
   Result := 3;
  NORMAL:
   Result := 5;
  MAXIMUM:
   Result := 7;
  ULTRA:
   Result := 9;
 else
  Result := 5;
 end;
end;

procedure X;
begin
var
 Archivformat: TGUID;
 Archivename: string;
 Arch: I7zOutArchive;
begin
 Archivformat := CLSID_CFormat7z;
 Arch := CreateOutArchive(Archivformat);

 Archivename := 'archive.7z';

 // Add a progress bar ...
 Arch.SetProgressCallback(nil, ProgressCallback);

 Arch.AddFile('1.mp4', '1.mp4');
 Arch.AddFile('2.mp4', '2.mp4');
 BytesToCopy := TFile.GetSize('1.mp4') + TFile.GetSize('2.mp4'); // Test

 // Compression level 0-9
 SetCompressionLevel(Arch, CompressionStrength(TCompressStrength.ULTRA));

 // 7z options
 if Archivformat = CLSID_CFormat7z then
  begin
   // ==============================================================================================================================================
   // Compression method
   SevenZipSetCompressionMethod(Arch, T7zCompressionMethod.m7LZMA);

   // Multithreading
   SetMultiThreading(Arch, CPUCount);

   // Compress headers
   SevenZipCompressHeaders(Arch, True);

   SetDictionnarySize(Arch, 63); // 0-63

   // Encrypt headers
   SevenZipEncryptHeaders(Arch, True);

   // Encrpytion method is always AES265
   // ==============================================================================================================================================
  end
 else
  // ZIP options
  if Archivformat = CLSID_CFormatZip then
   begin
    // ==============================================================================================================================================
    // Compression method (LZMA not available)
    SetCompressionMethod(Arch, TZipCompressionMethod.mzBZip2);

    // Multithreading
    SetMultiThreading(Arch, CPUCount);

    // Dictionnary size
    SetDictionnarySize(Arch, 32); // 0-32

    // Encryption method
    SetEncryptionMethod(Arch, TZipEncryptionMethod.emAES256);

    // Number deflate passes
    SetDeflateNumPasses(Arch, 2); // 1-?

    // Number fast bytes
    SetNumFastBytes(Arch, 256); // max 0-?
    // ==============================================================================================================================================
   end;

  // Set a password if necessary
  Arch.SetPassword('password');

  // Save to file
  Arch.SaveToFile(Archivename);
 end;
Procedure SetCompressionLevel abgeändert in das da unten funktioniert auch nicht. Immer Fehler Bereichsprüfung.
Delphi-Quellcode:
procedure SetCompressionLevel(Arch: I7zOutArchive; level: Cardinal);
begin
  SetCardinalProperty(arch, 'X', level);
 
  // TEST

  if level <= 9 then
   begin
    if level >= 9 then
     SetDictionnarySize(Arch, kLzmaDicSizeX9)
    else if level >= 7 then
     SetDictionnarySize(Arch, kLzmaDicSizeX7)
    else if level >= 5 then
     SetDictionnarySize(Arch, kLzmaDicSizeX5)
    else if level >= 3 then
     SetDictionnarySize(Arch, kLzmaDicSizeX3)
    else
     SetDictionnarySize(Arch, kLzmaDicSizeX1);
   end
  else
   raise Exception.Create(RsCompressionUnavailableProperty);
end;

KodeZwerg 29. Apr 2023 15:12

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal eine Test-Anwendung erstellt.
Bei weitem nicht fertig, aber so das grundlegende funktioniert.
Es kann für x86 oder x64 kompiliert werden.
Es kann mehrere Dateien aufnehmen.
Es kann alle Unterstützten Methoden anwenden.
Es kann alle Kompressions-Stufen verarbeiten.

Es zeigt keinen Status.
Es legt die Dateien mit einem absoluten Pfad an :-(

Es funktioniert :-)

Alle benötigten Dateien für das Projekt sind enthalten, auch die 7-Zip Bibliotheken.

KodeZwerg 29. Apr 2023 21:08

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Ps: DieDolly, les doch mal was da im sevenzip.pas steht, da wird dir doch per X gezeigt was erlaubt ist und was nicht.
Also das was du möchtest, SetDictionnarySize, ist nur für das Zip und BZip2 format (CLSID_CFormatZip, CLSID_CFormatBZ2) verfügbar.
Code:
                                                                                             //  ZIP 7z GZIP BZ2
  procedure SetCompressionLevel(Arch: I7zOutArchive; level: Cardinal);                       //   X  X  X  X
  procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal);                   //   X  X      X

  procedure SetCompressionMethod(Arch: I7zOutArchive; method: TZipCompressionMethod);        //   X
  procedure SetEncryptionMethod(Arch: I7zOutArchive; method: TZipEncryptionMethod);          //   X
  procedure SetDictionnarySize(Arch: I7zOutArchive; size: Cardinal); // < 32                 //   X          X
  procedure SetMemorySize(Arch: I7zOutArchive; size: Cardinal);                              //   X
  procedure SetDeflateNumPasses(Arch: I7zOutArchive; pass: Cardinal);                        //   X      X  X
  procedure SetNumFastBytes(Arch: I7zOutArchive; fb: Cardinal);                              //   X      X
  procedure SetNumMatchFinderCycles(Arch: I7zOutArchive; mc: Cardinal);                      //   X      X


  procedure SevenZipSetCompressionMethod(Arch: I7zOutArchive; method: T7zCompressionMethod); //       X
  procedure SevenZipSetBindInfo(Arch: I7zOutArchive; const bind: UnicodeString);             //       X
  procedure SevenZipSetSolidSettings(Arch: I7zOutArchive; solid: boolean);                   //       X
  procedure SevenZipRemoveSfxBlock(Arch: I7zOutArchive; remove: boolean);                    //       X
  procedure SevenZipAutoFilter(Arch: I7zOutArchive; auto: boolean);                          //       X
  procedure SevenZipCompressHeaders(Arch: I7zOutArchive; compress: boolean);                 //       X
  procedure SevenZipCompressHeadersFull(Arch: I7zOutArchive; compress: boolean);             //       X
  procedure SevenZipEncryptHeaders(Arch: I7zOutArchive; Encrypt: boolean);                   //       X
  procedure SevenZipVolumeMode(Arch: I7zOutArchive; Mode: boolean);                          //       X

KodeZwerg 30. Apr 2023 09:24

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Liste der Anhänge anzeigen (Anzahl: 2)
Nach längerem testen habe ich festgestellt das die alte API inkompatibel zu den Bibliotheken ist.
Es wurde zwar kein Fehler gemeldet aber stur nur mit LZMA archiviert.
Im Anhang sind für x86 und x64 funktionierende Bibliotheken und Test-Anwendungen.
Merkwürdiger weise interessiert es der dll nicht welche Kompressionslevel ich angebe aber die Methoden funktionieren nun.
Die BZip2 Methode lässt bei mir die Applikation einfrieren, der Rest funktioniert.
Die Test-Anwendungen sind nun (abgesehen vom BZip2 und das ignorieren des Levels) stabil.
Die Datei Liste wurde überarbeitet und lässt keine doppelten Dateien mehr zu. (nur wenn sie aus verschiedenen Verzeichnissen abstammen)
Drag und Drop aus dem Explorer für Dateien oder Verzeichnisse wurde integriert.
In den Archiven wird nun der Pfad korrekt abgelegt, es wird aus allen Dateien der niedrigste gemeinsame Pfad ermittelt und im Archiv verwendet.
Passwort Verschlüsselung und Anzahl der Threads wurde hinzugefügt.

DieDolly 30. Apr 2023 13:11

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Danke für die Demo und das Testen.

Es muss doch eine andere Möglichkeit geben, um bzip2, deflate usw zum Laufen zu bekommen. Eine DLL von 2009 kann nicht die Lösung sein.
Die API setzt das Property 0 (Null) für die Kompressionsmethode. Vielleicht ist das veraltet bzw. die Namensgebung
Delphi-Quellcode:
SevCompressionMethod: array[T7zCompressionMethod] of UnicodeString = ('COPY', 'LZMA', 'BZIP2', 'PPMD', 'DEFLATE', 'DEFLATE64');

Für das LZMA-Problem habe ich eine Lösung. In der SetMultithreading-Prozedur steht normalerweise
Delphi-Quellcode:
procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal);
begin
 SetCardinalProperty(arch, 'MT', ThreadCount);
end;
Das abgeändert zu dem hier und das LZMA-Problem ist weg
Delphi-Quellcode:
procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal);
begin
 // SetCardinalProperty(arch, 'MT', ThreadCount);

 if ThreadCount > 1 then
  SetCardinalProperty(arch, 'MT', ThreadCount)
 else if ThreadCount <= 0 then
  SetBooleanProperty(arch, 'MT', False);
end;
Das Problem liegt also bei 7z selbst.

Vielleicht hilft die Community ja mit, dass Delphi endlich eine sehr gut funktionierende 7z-DLL-API bekommt. Die von Jedi in allen Ehren, aber die ist nix.

Was mir auch aufgefallen ist:
- Kompressionslevel SAVE und Kompressionsmethode COPY funktionieren nur im Single-Threaded-Modus
-- funktionieren außerdem nur, wenn EncryptHeaders nicht an ist. Ist EncryptHeaders an, sind wir wieder beim LZMA-Problem.

Die hier vorgestellte API schreibt die 7z Kompressionsmethode ins Property 0 (Null). Ich weiß nicht wie aktuell diese Seite ist, aber hier ist die Rede vom Property N https://sevenzip.osdn.jp/chm/cmdline...d.htm#MethodID

Will man das machen kommt aber wieder nur, wie immer "Fehler bei Bereichsprüfung"

KodeZwerg 30. Apr 2023 13:58

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521833)
Danke für die Demo und das Testen.

Gerne!

Zitat:

Zitat von DieDolly (Beitrag 1521833)
Es muss doch eine andere Möglichkeit geben, um bzip2, deflate usw zum Laufen zu bekommen. Eine DLL von 2009 kann nicht die Lösung sein.

Naja, die Header sind von 2009, von daher bleibe ich nun auch beim testen bei diesen alten Bibliotheken.

Zitat:

Zitat von DieDolly (Beitrag 1521833)
Das Problem liegt also bei 7z selbst.

Oder die Header Übersetzung... Du siehst ja das nicht alles so klappt wie man eigentlich vermuten sollte.

Zitat:

Zitat von DieDolly (Beitrag 1521833)
- Kompressionslevel SAVE und Kompressionsmethode COPY funktionieren nur im Single-Threaded-Modus
-- funktionieren außerdem nur, wenn EncryptHeaders nicht an ist. Ist EncryptHeaders an, sind wir wieder beim LZMA-Problem.

Also die 7z.dll macht irgendwie schon das was sie sollte, nur eben nicht alles.
Abgesehen von BZip2, Kompressions Level und Threads, arbeitet es einwandfrei.
Das mit den Threads ist mir erstmal gar nicht so ins Auge gefallen da ich mich mehr auf die erzeugten Archive fokusiert hatte.

Deinen Patch kann ich nicht nachvollziehen.
Delphi-Quellcode:
procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal);
begin
//  SetCardinalProperty(arch, 'MT', ThreadCount);
 if (ThreadCount > 1) then
   SetCardinalProperty(arch, 'MT', ThreadCount)
 else
   if (ThreadCount <= 0) then
     SetBooleanProperty(arch, 'MT', False);
end;
Macht doch das gleiche wie
Delphi-Quellcode:
procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal);
begin
  SetCardinalProperty(arch, 'MT', ThreadCount);
end;
(Boolean False wird doch zu einer 0)

So sieht meine "Pack" routine aus:
Delphi-Quellcode:
procedure TfrmMain.btnCreateClick(Sender: TObject);
var
  Arch: I7zOutArchive;
  fn: string;
  i: Integer;
  len: Integer;
begin
  if (lbFiles.Items.Count > 0) then
    if sdCreate.Execute(Self.Handle) then
      begin
        // update UI
        btnAdd.Enabled := False;
        btnClear.Enabled := False;
        edtPassword.Enabled := False;
        gbLevel.Enabled := False;
        rgMethod.Enabled := False;
        cbThreads.Enabled := False;
        cbThread.Enabled := False;
        Application.ProcessMessages;
        Sleep(1);
        // begin creating internal archive format
        Arch := CreateOutArchive(CLSID_CFormat7z);
        // store filename
        fn := sdCreate.FileName;
        // calculate the number of chars to be stripped
        if (lbFiles.Items.Count > 1) then
          len := Succ(Length(FindCommonPath(PathDelim, lbFiles.Items.ToStringArray)));
        // compression level 0-9 (store - ultra)
        SetCompressionLevel(Arch, tbLevel.Position);
        // compression method
        case rgMethod.ItemIndex of
          0: SevenZipSetCompressionMethod(Arch, m7Copy);
          1: SevenZipSetCompressionMethod(Arch, m7LZMA);
          2: SevenZipSetCompressionMethod(Arch, m7BZip2);
          3: SevenZipSetCompressionMethod(Arch, m7PPMd);
          4: SevenZipSetCompressionMethod(Arch, m7Deflate);
          5: SevenZipSetCompressionMethod(Arch, m7Deflate64);
          else
            SevenZipSetCompressionMethod(Arch, m7Copy);
        end;
        // number of threads
        if ((not cbThread.Checked) and (cbThreads.Items.Strings[0] <> 'N/A')) then
          SetMultiThreading(Arch, Succ(cbThreads.ItemIndex))
        else
          SetMultiThreading(Arch, 0);
        // optional try archive settings
        SevenZipRemoveSfxBlock(Arch, True);
        SevenZipSetSolidSettings(Arch, True);
        SevenZipAutoFilter(Arch, True);
        SevenZipCompressHeaders(Arch, True);
        SevenZipCompressHeadersFull(Arch, True);
        SevenZipEncryptHeaders(Arch, True);
        // optional password encrypt
        if (edtPassword.Text <> '') then
          Arch.SetPassword(edtPassword.Text);
        // use progressbar
        Arch.SetProgressCallback(Self, ProgressCallback);
        // add files to archive, stripping leading folders
        if (lbFiles.Items.Count = 1) then
          Arch.AddFile(lbFiles.Items.Strings[0], ExtractFileName(lbFiles.Items.Strings[0]))
        else
          for i := 0 to Pred(lbFiles.Items.Count) do
            Arch.AddFile(lbFiles.Items.Strings[i], Copy(lbFiles.Items.Strings[i], Succ(len), (Length(lbFiles.Items.Strings[i]) - len)));
        // encode and write the archive
        Arch.SaveToFile(fn);
        // update UI
        btnAdd.Enabled := True;
        btnClear.Enabled := True;
        edtPassword.Enabled := True;
        gbLevel.Enabled := True;
        cbThread.Enabled := True;
        cbThreads.Enabled := ((not cbThread.Checked) and (cbThreads.Items.Strings[0] <> 'N/A'));
        rgMethod.Enabled := True;
        Application.ProcessMessages;
      end;
end;

DieDolly 30. Apr 2023 14:02

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Deinen Patch kann ich nicht nachvollziehen.
Macht doch das gleiche wie
Der Patch ist direkt von SourceForge. Wenn man MT auf 0 setzt, ist es nicht zwangsweise auf Off gesetzt. Das macht der Patch.

Ich würde mir sehr wünschen, dass es aktuelle Header gibt. Die von Jedi sind halt auch nicht gut. Mit den Jedis kann man nur bei Zip-Archiven die Kompressionsmethode wählen, bei 7z nicht.
Ich würde das ja erweitern, aber JclCompression ist eine einzige Katastrophe. Deswegen dachte ich an diese Bibliothek von https://github.com/mail2nnv/d7zip, welche letztes Jahr erst abgeändert wurde.

Für Delphi scheint es einfach nichts Brauchbares zu geben.

Tun wir uns doch zusammen, und bauen mal etwas, was heute funktioniert - eine funktionierende, von der DelphiPraxis ins Leben gerufene Delphi 7z-Bibliothek.

DieDolly 30. Apr 2023 16:23

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Ich habe ChatGPT mal gefragt ob das Ding helfen kann, aber die Antworten sind zu 75% falsch. Es werden Units eingebunden, die nichts mit der mit Delphi mitgelieferten sevenzip.pas oder mit der hier vorgestellten Bibliothek zu tun haben.

dummzeuch 30. Apr 2023 16:39

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Ich hatte gehofft, dass das einfach eine C API ist, aber anscheinend benutzt es Interfaces, die "irgendwie" initialisiert werden müssen (laut readme.txt im DOCS-Verzeichnis). Das ist mir auf die Schnelle zu komplex. d7zip macht das anscheinend auch.

Ich hätte nämlich definitiv Interesse an einer funtionierenden Import-Unit für die 7z.dll, da ich nach meinem Urlaub damit große Dateien ein- und auspacken wollte, und zwar idealerweise mit bzip2.
(Für ZIP funktionieren die jcl-Units problemlos, die verwenden wir schon seit Ewigkeiten.)

DieDolly 30. Apr 2023 16:47

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Genau, ZIP ist OK. Da kann man auch die Kompressionsmethode aussuchen. Bei 7z hört es dann aber schon auf, das ist wie ich finde eine grundlegende Option, die JclCompression nicht bietet.
Ja, ein Wunschtraum. Eine funktionierende, aktuelle Schnittstelle, damit man die 7z.dll richtig nutzen kann.
Ich kann es leider nicht, weil ich keine Ahnung habe. Aber warum scheint das Thema so uninteressant zu sein? Es gibt große Komponenten, ja. Aber 7z.dll ist einfach das Beste was man nutzen kann.

dummzeuch 30. Apr 2023 16:51

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521838)
Genau, ZIP ist OK. Da kann man auch die Kompressionsmethode aussuchen. Bei 7z hört es dann aber schon auf, das ist wie ich finde eine grundlegende Option, die JclCompression nicht bietet.
Ja, ein Wunschtraum. Eine funktionierende, aktuelle Schnittstelle, damit man die 7z.dll richtig nutzen kann.

Ich nehme mein Notebook mit in den Urlaub, aber ich glaube nicht, dass ich Zeit finden werde, mich damit zu beschäftigen.

KodeZwerg 30. Apr 2023 17:43

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Ich bin auch die nächsten zwei Wochen im Urlaub und rein vom Kopf her denke ich mir das es wohl nicht verkehrt sein kann sich mit der CLI Anwendung anzufreunden, die bietet halt nur das an was es tatsächlich auch gibt.
Die 7-Zip SDK Header sehen abschreckend aus.
Hier im Forum glaube ich auch vor einer Ewigkeit mal was von einer Custom-Übersetzung gesehen zu haben.

DieDolly 30. Apr 2023 17:55

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Die CLI-Anwendung hat sicher keinen dauerhaften Callback der über den Fortschritt Info gibt, oder?

mmw 30. Apr 2023 18:40

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Hallo,
evtl. interessant

https://github.com/geoffsmith82/d7zip

Gruß

DieDolly 30. Apr 2023 18:44

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
sevenzip.pas 12 Jahre alt, noch älter als die von mir im ersten Beitrag genannte. Die im ersten Beitrag genannte sevenzip.pas zeigt bei Github an, dass sie nur 1 Jahr alt ist. Kann ja auch sein, aber der Inhalt ist im Prinzip auch nur von vor über 10 Jahren.

mmw 30. Apr 2023 18:50

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Hallo,
stimmt. dafür sind die *.dll's aktueller

Gruß

himitsu 30. Apr 2023 18:51

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von dummzeuch (Beitrag 1521837)
Ich hätte nämlich definitiv Interesse an einer funtionierenden Import-Unit für die 7z.dll,

Es ginge soger komplett rein, als OBJ in die EXE gelinkt.

DieDolly 30. Apr 2023 18:57

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
DLL in Exe als Resource kenne ich, aber was hat es mit Obj-Dateien aufsich? Sind Obj-Dateien leichter zu behandeln, braucht es dafür keinen komplizierten Wrapper mehr?

mytbo 30. Apr 2023 21:14

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von dummzeuch (Beitrag 1521837)
Ich hätte nämlich definitiv Interesse an einer funtionierenden Import-Unit für die 7z.dll, da ich nach meinem Urlaub damit große Dateien ein- und auspacken wollte, und zwar idealerweise mit bzip2.

Wenn es auch die mORMot Unit mormot.lib.win7zip sein darf, dann zum Beispiel so:
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.text,
  mormot.core.test,
  mormot.core.os,
  mormot.lib.win7zip;

var
  zipFileName: TFileName;
  libReader: I7zReader;
  libWriter: I7zWriter;
  content: RawByteString;
begin
  content := TSynTestCase.RandomIdentifier(1 shl 12);
  zipFileName := MakePath([Executable.ProgramFilePath, 'TestDaten.7z']);

  libWriter := New7zWriter(fh7z); // fhBZip2
  libWriter.SetCompressionLevel(3); // x Parameter (1/3/5/7/9), default 5
  libWriter.AddBuffer('Daten\TestDaten.dat', content);
  libWriter.SaveToFile(zipFileName);
  libWriter := Nil;

  libReader := New7zReader(zipFileName);
  var libData: RawByteString := libReader.Extract('Daten\TestDaten.dat');
  if (Length(content) = Length(libData))
    and CompareMem(Pointer(content), Pointer(libData), Length(content)) then
  begin
    ShowMessage('Ok!');
  end;
Bis bald...
Thomas

DieDolly 30. Apr 2023 21:17

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Ich denke mit 7z ist das einfacher und der Code ist selbsterklärend-"er".

Alter Mann 30. Apr 2023 22:08

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Liste der Anhänge anzeigen (Anzahl: 4)
Hallo,

nur so am Rande: Von welcher 7Zip.dll reden wir (siehe Anhang)?

Ich habe folgende im Angebot:

https://github.com/mail2nnv/d7zip = m2n.png
https://github.com/geoffsmith82/d7zip = hg_x86, hg_x64
Unbekannt = Unbekannt
KodeZwerg = m2n (bezogen auf die Versions-Nr. 4.65.0.0

himitsu 30. Apr 2023 22:32

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521848)
DLL in Exe als Resource kenne ich, aber was hat es mit Obj-Dateien aufsich? Sind Obj-Dateien leichter zu behandeln, braucht es dafür keinen komplizierten Wrapper mehr?

OBJ ist ein vorkompilierter Code (egal von welcher Programmiersprache), welcher direkt in unsere Kompilate integriert werden kann. (bissl vergleichbar mit unseren DCU)
Beispiele sind z.B. die Funktionen von MIDAS (MidasLib.pas), ZLib (System.ZLib.pas oder IdZLibHeaders.pas), RegEx (System.RegularExpressionsAPI.pas > System.RegularExpressions.pas), JPEG (Vcl.Imaging.jpeg.pas), PNG (nicht mehr) oder Delphi-Referenz durchsuchenDelayed-Loading (SysInit.pas).


Die DLL in den Resourcen mußt du erst draußen speichern, um sie zu laden, oder etwas böser in den RAM laden und manuell von dort laden. (und hoffen der Virenscanner hat nix dagegen)


Theoretisch kann man nahezu jeden C++-Code als OBJ kompileren und so ins Delphi pringen.
Ich bin noch am Experimentieren, GIT so ins Delphi zu bekommen, also um optimaler damit zu arbeiten. (Beispiel ist TortoiseGit, welches teilweise die GitLib integriert hat, aber auch teilweise direkt mit der GIT.exe redet ... z.B. Krank beim Revert jede Datei mit je zwei GIT.exe-Aufrufen extrem langsam und Anderes aber intern sehr schnell)

Zitat:

Zitat von Alter Mann (Beitrag 1521853)
nur so am Rande: Von welcher 7Zip.dll reden wir (siehe Anhang)?

Am Besten vom aktuellen Original?
https://7-zip.de/download.html

KodeZwerg 30. Apr 2023 22:33

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521852)
Ich denke mit 7z ist das einfacher und der Code ist selbsterklärend-"er".

Die Aufrufe sind analog zur sevenzip.pas.
Zitat:

Zitat von mytbo (Beitrag 1521851)
Wenn es auch die mORMot Unit mormot.lib.win7zip sein darf

Auf jeden Fall (jedenfalls von meiner Seite her)
Ich habe es so versucht, jedoch ohne Erfolg beim umstellen des SetCompressionLevel, da ich daran schon scheitere habe ich die weiteren features nicht weiter angerührt.
Delphi-Quellcode:
procedure TfrmMain.btnCreateClick(Sender: TObject);
var
  zipFileName: TFileName;
  libWriter: I7zWriter;
begin
  zipFileName := MakePath([Executable.ProgramFilePath, 'TestDaten.7z']);
  if (cbFormat.ItemIndex <= 0) then
    cbFormat.ItemIndex := 7;
  libWriter := New7zWriter(T7zFormatHandler(cbFormat.ItemIndex), '7z.dll');
//  libWriter := New7zWriter(fh7z, '7z.dll');
  libWriter.SetCompressionLevel(cbLevel.ItemIndex);
//  libWriter.SetCompressionLevel(0); // von 0 bis 9 alle getestet, es kommt immer das gleiche raus
  libWriter.SetCompressionMethod(TZipCompressionMethod(cbMethod.ItemIndex));
//  libWriter.SetCompressionMethod(mzLzma);
  libWriter.AddFile('7z.dll', '7z.dll');
  libWriter.SaveToFile(zipFileName);
  libWriter := Nil;
end;
(die auskommentierten zeilen zeigen was sich hinter meinen Indexen verbirgt)
Aber sehr positiv zu erwähnen, BZip2 funktioniert.
Da ich in der mormot.lib.win7zip.pas Datei leider keine Informationen finde auf welcher Bibliothek-Version es basiert habe ich es mit der aktuellen 64bit 7z.dll (22.1.0.0) getestet.

Alter Mann 30. Apr 2023 22:54

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Am Besten vom aktuellen Original?
Also die 22.01 von hg oder dem Original:).

Da hätten wir dann auch gleich die(?) Ausgangsbasis(hg).

mytbo 30. Apr 2023 23:38

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von KodeZwerg (Beitrag 1521855)
Ich habe es so versucht, jedoch ohne Erfolg beim umstellen des SetCompressionLevel, da ich daran schon scheitere habe ich die weiteren features nicht weiter angerührt.

Ich habe es mit der 32-Bit Version 22.01 der 7za.dll getestet. Wenn die DLL im Programmverzeichnis liegt, gebe keinen Bibliothekspfad an, mORMot sucht sie. Laut dieser Beschreibung sind für den CompressionLevel die Werte 1/3/5/7/9 zulässig. Bei mir funktioniert es. Du darfst es nicht mit den synthetischen Random-Testdaten versuchen, damit ist ab einem gewissen Level jeder Algorithmus überfordert.
Delphi-Quellcode:
var
  zipFileName: TFileName;
  libReader: I7zReader;
  libWriter: I7zWriter;
  content: RawByteString;
begin
  content := StringFromFile(MakePath([Executable.ProgramFilePath, 'mormot.lib.openssl11.pas']));
  zipFileName := MakePath([Executable.ProgramFilePath, 'TestDaten.7z']);

  libWriter := New7zWriter(fh7z);
  libWriter.SetCompressionLevel(7); // x Parameter (1/3/5/7/9)
  libWriter.AddBuffer('Lib\mormot.lib.openssl11.pas', content);
  libWriter.SaveToFile(zipFileName);
  libWriter := Nil;

  libReader := New7zReader(zipFileName);
  var libData: RawByteString := libReader.Extract('Lib\mormot.lib.openssl11.pas');
  if (Length(content) = Length(libData))
    and CompareMem(Pointer(content), Pointer(libData), Length(content)) then
  begin
    ShowMessage('Ok!');
  end;
Benchmark-Werte:
LevelDateigrößeLaufzeit [ms]
Original340.019 
154.03511
353.74211
548.81135
747.95942
947.95942

Bis bald...
Thomas

KodeZwerg 1. Mai 2023 00:16

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Thomas Dankeschön für Dein weiteres Beispiel samt Erklärung und den Link!
Delphi-Quellcode:
libWriter.SetCompressionMethod();
Das mag er nicht, habe es nun mit der 64bit 7za.dll v22.1.0.0 (ohne dll Angabe) erfolgreich getestet (Level 0 = copy, alles darüber ist LZMA2)
(Ich bin beim AddFile() geblieben)
Zitat:

Zitat von mytbo (Beitrag 1521857)
Du darfst es nicht mit den synthetischen Random-Testdaten versuchen, damit ist ab einem gewissen Level jeder Algorithmus überfordert.

Das habe ich nicht verstanden, aber hey, nun akzeptiert er meinen Input :-D

himitsu 1. Mai 2023 00:22

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von mytbo (Beitrag 1521857)
Laut dieser Beschreibung sind für den CompressionLevel die Werte 1/3/5/7/9 zulässig. Bei mir funktioniert es.

Von 0 bis 9 ist alles möglich, aber die geraden Werte werden einfach abgerundet, da sie nicht implementiert sind.
Selbes gilt übrigens auch für ZIP.

LZ4 wäre hier eine nette Sache, aber eigentlich hätte ich es gern in einer zip-Datei, anstatt in einer 7z.
Und auch wenn man hier 7-Zip dafür verwenden könnte etwas im Buffer/RAM zu komprimieren.
Eine sauschnelle Komprimierung bietet viele Vorteile (auch wenn es nicht unbedingt extrem viel Platz einspart)

dummzeuch 1. Mai 2023 08:45

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von Alter Mann (Beitrag 1521853)
Von welcher 7Zip.dll reden wir (siehe Anhang)?

Ich habe folgende im Angebot:

https://github.com/mail2nnv/d7zip = m2n.png
https://github.com/geoffsmith82/d7zip = hg_x86, hg_x64
Unbekannt = Unbekannt
KodeZwerg = m2n (bezogen auf die Versions-Nr. 4.65.0.0

Ich verwende immer die aus dem offiziellen Installer von https://www.7-zip.org . Für Delphi immer die 32 Bit dll, weil ich außer ein paar Tests keine 64 Bit Delphi Projekte habe.

dummzeuch 1. Mai 2023 08:48

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von himitsu (Beitrag 1521854)
Die DLL in den Resourcen mußt du erst draußen speichern, um sie zu laden, oder etwas böser in den RAM laden und manuell von dort laden. (und hoffen der Virenscanner hat nix dagegen)

Es geht auch ohne, zumindest mit den meisten DLLs (7zip habe ich nicht probiert). Ich habe dafür eine Unit, die sich um Relocation und ermitteln der Entry-Points kümmert. Da wird nichts auf Platte gespeichert.

Allerdings warte ich jeden Tag darauf, dass die Virenscanner darauf allergisch reagieren.

dummzeuch 1. Mai 2023 08:52

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von mytbo (Beitrag 1521851)
Zitat:

Zitat von dummzeuch (Beitrag 1521837)
Ich hätte nämlich definitiv Interesse an einer funtionierenden Import-Unit für die 7z.dll, da ich nach meinem Urlaub damit große Dateien ein- und auspacken wollte, und zwar idealerweise mit bzip2.

Wenn es auch die mORMot Unit mormot.lib.win7zip sein darf

Definitiv. Werde ich mir nach meiner Rückkehr ansehen. Danke für den Hinweis.

DieDolly 1. Mai 2023 09:10

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Wie verwendet man dieses mormot?

Geht das mit dem
Delphi-Quellcode:
StringFromFile(MakePath())
einfacher? Ich verstehe diese Zeile nicht so richtig. Ich habe das mit AddBuffer und Content einfach weggelassen und nehme stattdessen AddFile.
Fortschrittsanzeige, geht das auch mit mormot?^Weil das hier funktioniert nicht wie mit der sevenzip.pas
Delphi-Quellcode:
function ProgressCallback(Sender: I7zArchive; current, total: Int64): HRESULT;
begin
 if total >= BytesTotalToCopy then
  Form1.ProgressBar1.Max := 100
 else
  Form1.ProgressBar1.Position := ...;

 Result := S_OK;
end;

libWriter.SetProgressCallback(ProgressCallback); // Inkompatible Typen: 'Methodenzeiger und reguläre Prozedur'
Ich sehe gerade, was mormot aber auch nicht kann, warum auch immer: ein 7z Archiv erstellen mit Kompressionsstärke "Speichern", keine Kompressionsmethode, weil nicht notwendig bei nur "Speichern", EncryptHeaders und Passwort. Das Archiv wird trotzdem mit LZMA komprimiert.

Zitat:

Aber sehr positiv zu erwähnen, BZip2 funktioniert.
BZip2 funktioniert nur, wenn EncryptHeaders7z=False und kein Passwort gesetzt ist. Ansonsten gehts wieder zurück zu LZMA.
Egal was man macht, setzt man EncryptHeaders, setzt das den vom Nutzer gesetzten Wert von SetCompressionLevel zu LZMA zurück.

Keine der Bibliotheken scheint richtig zu funktionieren, egal wie alt. Liegt das Problem bei 7z selber?

KodeZwerg 1. Mai 2023 09:57

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Bei meinen gestrigen tests, mit mORMot2, lasse unbedingt die zeile mit dem setzen einer methode weg @DieDolly, dann hast Du zugriff auf das Level, 0-9, wobei nur die von Thomas genannten werte dann dabei einen unterschied machen.
Es scheint, als ob das Level nur für LZMA2 funktioniert, sobald Du eine "custom-Methode" einbindest, wird das Level ignoriert.
Ich werde mir mal eine UI basteln in dem alles aufgeführt was möglich ist um es dann stück für stück zu testen, mit der Möglichkeit es auch abzuschalten.
Vielleicht ist ja auch für die API nichts vorgesehen um jede mögliche Einstellung die es gibt anzuwenden ...
Von meiner Seite her, ich bin mit der mORMot2 mehr zufrieden als mit der sevenzip.pas :thumb:

@dummzeuch, redest Du zufällig vom BTMemoryModule? Wenn nicht wäre ich echt begeistert Dein laden aus der Resource kennenzulernen :cyclops:

DieDolly 1. Mai 2023 10:10

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
So ganz verstehe ich deine Antwort nicht.
Ich halte mich da an die UI von 7z selber. Schaltet man das Level SPEICHERN (0) ein, kann man dort keine Kompressionsmethode wählen.
So gehe ich auch vor, also setze ich nur das Level, aber keine Methode. Aber selbst wenn man die manuell auf Copy setzt, gehts zurück zu LZMA (alles mit EncryptHeaders)

Es funktioniert also nicht. Beide Bibliotheken haben dieselbenm Probleme.

Nochmal zusammengefasst:
setzt man EncryptHeaders, kann man Level=SPEICHERN nicht nutzen, da es dann immer LZMA ist. Die 7z-UI kann das alles anders. Es funktioniert wunderbar, bis man ein Passwort und EncryptHeaders setzt :(

Ansonsten bin ich auch zufrieden. Die Aufrufe sind einfach und kurz. Nur das mit der 7z.dll ist komisch. Und für den ProgressCallback bin ich zu doof.

Das mit dem Callback habe ich so gemacht
Delphi-Quellcode:
type
 TProgressCallback = class
 public
  function OnProgress(const Sender: I7zArchive; current, total: Int64): HRESULT;
 end;

// Beim Aufruf
ProgressCallback := TProgressCallback.Create;
libWriter := New7zWriter(fh7z);
libWriter.SetProgressCallback(ProgressCallback.OnProgress);

mytbo 1. Mai 2023 13:53

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521866)
Es funktioniert also nicht. Beide Bibliotheken haben dieselbenm Probleme.

Der Funktionsumfang der Bibliotheken 7z.dll, 7za.dll und 7zxa.dll unterscheidet sich erheblich. Auch die Möglichkeiten der einzelnen Kompressionsalgorithmen unterscheiden sich. Alles in allem eine große Anzahl an Kombinationen. Ein Blick in eine Beschreibung oder den Sourcecode erspart das Probieren. Die 7za.dll akzeptiert zum Beispiel für den CompressionLevel die Werte m7Copy, m7Lzma und m7Ppmd, aber nicht m7BZip2, m7Deflate und m7Deflate64. Die Exception Message "Falscher Parameter" weist darauf hin. Den ProgressCallback realisierst du wie folgt:
Delphi-Quellcode:
  ...
  private
    function ProgressCallback(const pmcSender: I7zArchive; pmCurrent, pmTotal: Int64): HRESULT;

function ...ProgressCallback(const pmcSender: I7zArchive; pmCurrent, pmTotal: Int64): HRESULT;
const
  STEP_WIDTH = 2;
var
  percentDone: Integer;
begin
  Result := S_OK;
  if pmCurrent = 0 then
  begin
    ProgressBar.Min := 0;
    ProgressBar.Max := 100;
    ProgressBar.Position := 0;
  end
  else if pmCurrent >= pmTotal then
    ProgressBar.Position := 0
  else
  begin
    percentDone := Trunc(pmCurrent / (pmTotal / 100));
    if (ProgressBar.Position + STEP_WIDTH) < percentDone then
      ProgressBar.Position := percentDone;
  end;
end;

var
  zipFileName: TFileName;
  libWriter: I7zWriter;
begin
  zipFileName := MakePath([Executable.ProgramFilePath, 'TestDaten.7z']);

  var timer: TPrecisionTimer;
  libWriter := New7zWriter(fh7z);
  libWriter.SetCompressionLevel(3);
  libWriter.SetProgressCallback(ProgressCallback);
  timer.Start;
  libWriter.AddFiles('c:\...\mORMot2\src\', '', '*', True);
  libWriter.SaveToFile(zipFileName);
  ShowMessage(timer.Stop);
Die Funktion
Delphi-Quellcode:
MakePath([Executable.ProgramFilePath, 'TestDaten.7z']);
macht das, was der Name sagt. Die mORMot Lösungen sind nur viel pragmatischer als die Delphi Bordmittel.

Bis bald...
Thomas

DieDolly 1. Mai 2023 14:06

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Dass es da so einen großen Unterschied gibt, wusste ich nicht. Heißt das im Umkerhschluss, dass die 7z.dll alles drin hat?

mytbo 1. Mai 2023 14:14

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Zitat:

Zitat von DieDolly (Beitrag 1521871)
Dass es da so einen großen Unterschied gibt, wusste ich nicht. Heißt das im Umkerhschluss, dass die 7z.dll alles drin hat?

Ja, wie dokumentiert. 7za.dll hat deutlich weniger und 7zxa.dll ist fast blank.

Bis bald...
Thomas

DieDolly 1. Mai 2023 14:34

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Das Problem, wenn man EncryptHeaders aktiviert und der Komprimierungslevel automatisch von 0 auf 9 gesetzt wird und LZMA statt Copy, ist aber bestimmt trotzdem ein Fehler der DLL.

himitsu 1. Mai 2023 14:47

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Und noch etwas zum ersten Post

Zitat:

Delphi-Quellcode:
function ProgressCallback(Sender: Pointer; Total: Boolean; Value: Int64): HRESULT; stdcall;
begin
 BytesCopied := Value; // Test

 if Total then
  Form1.ProgressBar1.Max := 100
 else
  Form1.ProgressBar1.Position := GetPercent(BytesToCopy, BytesCopied);

 Result := S_OK;
end;

Arch.SetProgressCallback(nil, ProgressCallback);

Rate mal, warum solche Funktionen fast immer sowas wie einen frei benutzbaren "Data"-Parameter besitzen?

Delphi-Quellcode:
function ProgressCallback(Sender: Pointer; Total: Boolean; Value: Int64): HRESULT; stdcall;
begin
 //if Total then
 //  TForm1(Sender).ProgressBar1.Max := 100
 //else
 //  TForm1(Sender).ProgressBar1.Position := GetPercent(BytesToCopy, Value);

 if Total then begin
   TForm1(Sender).FBytesToCopy := Value;
   TForm1(Sender).ProgressBar1.Max := 100;
 end else
   TForm1(Sender).ProgressBar1.Position := GetPercent(TForm1(Sender).FBytesToCopy, Value);

 Result := S_OK;
end;

Arch.SetProgressCallback(Pointer(Form1), ProgressCallback);

EdAdvokat 1. Mai 2023 17:57

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Hallo zusammen,
eure Diskussion finde ich recht interessant, auch wenn ich selbst da nicht so der Fuchs bin.
Ich habe da mal so einiges zu 7zip recherchiert und bin da auf folgenden Beitrag aus der DP gestoßen.
Möglicherweise hilft der etwas weiter. Der Motzi hat im #17 ein Demoprogramm gepostet, das euch möglicherweise
weiter bringen könnte.

Wenn es völlig daneben sein sollte, bitte Entschuldigung.

https://www.delphipraxis.net/108543-...einbinden.html

Bei Torry.net habe ich auch noch was gefunden. Ist leider auch nicht ganz neu:

https://torry.net/quicksearchd.php?S...nzip&Title=Yes

DieDolly 1. Mai 2023 18:10

AW: d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ..
 
Kann man mit dem I7zWriter von mormot auch leere Verzeichnisse ins Archiv einbringen?

Ich verzweifle da gerade dran.

Delphi-Quellcode:
   libWriter.AddFile('1\1 2 3.txt', '1\1 2 3.txt');
   libWriter.AddFile('empty123', 'empty123');
   libWriter.SaveToFile(FileName);
Am Ende ist nur die Textdatei im Archiv.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:28 Uhr.
Seite 1 von 2  1 2      

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