1

I want my app to use files from a .7z file.

I have found some explanations of how to decompress a 7z file. However, they are all about a case I have not yet encountered in the wild: An archive that decompresses to a single file. I would expect a .7z archive to decompress to an arbitrary amount of files, possibly in arbitrary subfolders.

It seems like it would be possible to do this by including the whole 7zip application and then running that in a process. However, that seems like unnecessary extra steps, considering there's an official LZMA SDK. Also, it leads to problems concerning cross compatibility.

So, how can I unpack a .7z archive into a given folder, using in C# (.NET 3.5)?

Additional info from comments

"Please show the code that isn't working."
Well, at the moment I'm using the second half of this answer on another question. However, I'm expecting that to not do what I want - output (just like input) is a FileStream, so it's clear that this only creates one file.
It shows that Decoder is the class doing the decompressing, but it doesn't have a method that works with e.g. a DirectoryInfo, a string path or anything like that - it's all one file in, one file out. Every info I found on using the SDK does this very same thing; I haven't found a single one extracting an archive to several files.

Raphael Schmitz
  • 342
  • 1
  • 13
  • Is there some reason not to just Process.Start() 7z.exe with the command line arguments you are looking for or are you looking for source that understands the 7z archive? https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start?view=netframework-4.8 – Thoryn Hawley May 17 '19 at 17:27
  • Either include the 3 required files (7za.exe, 7az.dll, & 7zxa.dll) in your project and launch it with the `Process` class, or use the LZMA SDK library as you noted above. What specific issue are you running into? Please show the code that isn't working. – Rufus L May 17 '19 at 17:41
  • @RufusL Thank you, for your comment. I want to avoid the .exe solution because **A)** It's more crude, but at the same time more complex in the sense that more things that can go wrong. A missing file would become a runtime- instead of a compiler error etc. **B)** This is to be used in Unity3D, which can be built for Windows, Linux, iOS, Android, PS4, WebGL and many more. I added the info about "code that isn't working" to the question itself. – Raphael Schmitz May 20 '19 at 09:25
  • @ThorynHawley In short, "cross compatibility". I elaborated a little bit in my previous comment addressed at RufusL. – Raphael Schmitz May 20 '19 at 09:27

1 Answers1

2

I have come to the following conclusion:

Decompressing a .7z archive into a folder is not a feature provided by the C# LZMA SDK.

I'm afraid I have not found any hard evidence, like a blog post directly stating it.

However, I have found a description of the .7z file format. This description did not provide enough technical detail to craft a working solution, but it contained certain facts about the format:

In this section I will explain how the previous example is stored in the data Structured[...]

First up is the ​Header ​this contains just two variables: ​FileInfo​ and ​StreamsInfo.

FileInfo​ is probably the easiest structure to understand. It contains the name of each file in the 7z and a couple of other flags defining if the file is actually a directory or if the file is an empty file.

This structure is not reflected in the code of the C# SDK as far as I can see. That, combined with the information that the Decoder.Code() methods do not work with a directory path or more than one output Stream is a strong indicator.

So it seems that the C# part of the LZMA SDK only handles en- and decryption of a single file, or "Compressed Stream" as it is called in the linked document. The .7z archive format then counts as a separate format, which is ultimately a structure to contain an arbitrary number of compressed streams.

These streams can actually be combined in, again, arbitrary ways; e.g. an archive can contain files A and B compressed with LZMA, then add file C to the mix and compress it again with another algorithm. That makes decompressing a .7z archive more complex, which makes it even more of a pity that this functionality is not provided in the SDK.

Community
  • 1
  • 1
Raphael Schmitz
  • 342
  • 1
  • 13
  • One would thing a project existed wrapping the LZMA SDK to handle .7z etc...did anyone found one? One which is maintained? There seem to be few on nuget but which the is the best? – MrCalvin Jul 28 '19 at 08:41