SevenZipExtractor icon indicating copy to clipboard operation
SevenZipExtractor copied to clipboard

extraction multi file zip archive -> failes

Open muffmolch opened this issue 7 years ago • 8 comments

As it seems SevenZipExtractor cannot handle multi file archives, can it?

File.7z.001
File.7z.002
File.7z.003
using(ArchiveFile archiveFile = new ArchiveFile("File.7z.001")) {
   archiveFile.Extract(extractPath); // extract all
}

-> exception

muffmolch avatar Mar 08 '18 12:03 muffmolch

Interesting.

Every entry appears to have at least two properties, indicating the entry is split: IsSplitBeforeand IsSplitAfter (update to 1.0.12 to see these properties) If, for example, IsSplitBefore = true, this means the beginning of entry is in previous parts of archive.

simple entry.Extract(); is not working. My quick guess – to extract one entry one have to locate all parts first and merge all streams together in a single file. I didnt see any quick way of doing so in SevenZip interface.

Maybe someone can help?

adoconnection avatar Mar 10 '18 14:03 adoconnection

List<string> files = new List<string>()
{
    @"H:\SkyTest.part1.rar",
    @"H:\SkyTest.part2.rar",
    @"H:\SkyTest.part3.rar",
    @"H:\SkyTest.part4.rar",
    @"H:\SkyTest.part5.rar",
};

foreach (string file in files)
{
    using (ArchiveFile archiveFile = new ArchiveFile(file))
    {
        Console.WriteLine(Path.GetFileName(file).ToUpper());

        foreach (Entry entry in archiveFile.Entries)
        {
            Console.WriteLine(entry.FileName +  " - " + entry.IsSplitBefore + " - " + entry.IsSplitAfter);
        }
    }
}

adoconnection avatar Mar 10 '18 14:03 adoconnection

image

Добрый день. Для открытия многофайлового архива достаточно открыть первый архив?

AyratShigapov avatar Apr 10 '18 14:04 AyratShigapov

Hey there, looks like https://github.com/squid-box/SevenZipSharp implements multi-part archive support by creating an appended stream of all files. See the MultiStreamWrapper class here and InMultiStreamWrapper class here.

I'll be attempting this approach with SevenZipExtractor using the public ArchiveFile(Stream archiveStream, SevenZipFormat? format = null, string libraryFilePath = null) constructor to see if it works now.

Edit: I had no luck getting this working myself.

Cheers Fotis

fgimian avatar Aug 20 '22 00:08 fgimian

Is SevenZipSharp itself is capable of extracting multipart archives? If yes then its worth to dive in.

adoconnection avatar Aug 20 '22 07:08 adoconnection

Is SevenZipSharp itself is capable of extracting multipart archives? If yes then its worth to dive in.

I'll test it out thoroughly tonight and let you know mate, thanks so so much for your amazing library. 😊

fgimian avatar Aug 20 '22 07:08 fgimian

Okies, I've had some time to test this tonight with Squid-Box.SevenZipSharp and a multipart RAR file which I created from the PowerShell installer.

PS C:\Users\Fots\source\MultiTest.SevenZipSharp> dir C:\Users\Fots\Downloads\

    Directory: C:\Users\Fots\Downloads

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          19/08/2022  3:11 PM      106954752 PowerShell-7.2.6-win-x64.msi
-a---          20/08/2022  2:16 PM       26214400 PowerShell-7.2.6-win-x64.part1.rar
-a---          20/08/2022  2:16 PM       26214400 PowerShell-7.2.6-win-x64.part2.rar
-a---          20/08/2022  2:16 PM       26214400 PowerShell-7.2.6-win-x64.part3.rar
-a---          20/08/2022  2:16 PM       26214400 PowerShell-7.2.6-win-x64.part4.rar
-a---          20/08/2022  2:16 PM         893179 PowerShell-7.2.6-win-x64.part5.rar

With the following code, I can confirm that it does seem to handle the multipart archive:

using SevenZip;

string path = @"C:\Users\Fots\Downloads\PowerShell-7.2.6-win-x64.part1.rar";

SevenZipBase.SetLibraryPath(@"C:\Users\Fots\scoop\apps\7zip\current\7z.dll");
using SevenZipExtractor extractor = new(path);
extractor.ExtractArchive(@"C:\testing");

And as you can see, the extracted file is identical to the original MSI:

PS C:\Users\Fots\source\MultiTest.SevenZipSharp> dir C:\Users\Fots\Downloads\PowerShell-7.2.6-win-x64.msi, C:\testing\PowerShell-7.2.6-win-x64.msi

    Directory: C:\Users\Fots\Downloads

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          19/08/2022  3:11 PM      106954752 PowerShell-7.2.6-win-x64.msi

    Directory: C:\testing

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          19/08/2022  3:11 PM      106954752 PowerShell-7.2.6-win-x64.msi

PS C:\Users\Fots\source\MultiTest.SevenZipSharp> Get-FileHash C:\Users\Fots\Downloads\PowerShell-7.2.6-win-x64.msi, C:\testing\PowerShell-7.2.6-win-x64.msi

Algorithm       Hash                                                                   Path
---------       ----                                                                   ----
SHA256          77566D5B831523C6740C392B64237C52089B574F342A9F51D84ADED24E412CB8       C:\Users\Fots\Downloads\PowerShell-7.2.6-win-x64.msi
SHA256          77566D5B831523C6740C392B64237C52089B574F342A9F51D84ADED24E412CB8       C:\testing\PowerShell-7.2.6-win-x64.msi

Perhaps with your experience of the 7-Zip SDK, you would be able to understand how that library does it. I honestly really love the way your library works and would prefer to use it if possible. 😄

Huge thanks! Fotis

fgimian avatar Aug 20 '22 10:08 fgimian

The answer at https://sourceforge.net/p/sevenzip/discussion/45797/thread/79ecaee0/ may be helpful.

7z.dll requests another volumes from your app via IArchiveOpenVolumeCallback interface. So you must implement IArchiveOpenVolumeCallback in IArchiveExtractCallback object.

fgimian avatar Aug 20 '22 22:08 fgimian