`samantha-install-7z-dll`: Turning 7-Zip Into an Embeddable DLL

A deep dive into the archive engine that reads its own compressed metadata, routes bytes through callbacks, and makes a progress bar tell the truth.

11 min read • View on GitHub • More from larksuite

A towering archive vault stands inside a clockwork library, with nested drawers, compressed ledgers, and a small progress gauge fed by a long chain of files. The scene explains why 7z extraction is not a simple copy job, but a calculation about work, dependency, and output.
A 7z archive behaves more like a compressed database than a flat bundle, so progress has to track real work.
Key Takeaways

7z extraction looks like a file copy job until a solid archive forces the engine to do arithmetic. A tiny file at the end of the block can require megabytes of earlier decompression, so the progress bar is really reporting work, not file count. That single fact explains most of this repo's design.

A progress bar that has to do math

In a normal archive, the caller can estimate progress by counting files or bytes. In a solid 7z archive, that shortcut lies. The handler has to walk folders, estimate unpacked work, and keep `fromProgress` and `toProgress` honest even when the decompressor jumps across boundaries.

A close-up balance scale holds a tiny file on one side and a long coiled path of compressed data on the other. The illustration shows that progress is determined by the weight of hidden dependencies, not by the visible size of the destination file.
Solid archives make progress accounting a dependency problem, not a counter.

What this repo changes

The repo is a surgical wrapper around 7-Zip 22.01. It keeps the original archive machinery in `7zSrc`, but replaces the console-centric entry point with a class-based DLL interface that can be called from another Windows application. The goal is not to make 7-Zip simple. The goal is to make it embeddable without pretending the engine is any less serious.

Inside the archive engine

The core classes tell the story. `CHandler` owns the archive database in `CDbEx`, asks for properties like method and solid status, and then drives extraction. `CFolderOutStream` receives decompressed bytes one folder at a time, routes them to `IArchiveExtractCallback`, and updates CRCs as it writes. Empty files still need to exist in the model, even when they never pass through the byte stream.

The parser side is just as careful. `CStreamSwitch` lets `7zIn.cpp` hop between compressed header streams without losing state, and `ReadNumberSpec` decodes 7z's variable-length integers one bit pattern at a time. That is what a mature archive format looks like from the inside: metadata can be compressed, and the parser has to be ready for that.

The important path is not file by file. It is archive database, header stream, folder block, and output callback.

A narrow ink channel carries data through a checksum dial and into several jars, one full, one empty, and one only partly filled. The illustration shows how folder output, CRC validation, and empty-file handling can coexist in one stream pipeline.
The output side is not a dumb write loop. It is a routing problem with integrity checks attached.

Why the wrapper matters

What looks simpleWhat the engine actually doesWhy the DLL wrapper matters
Extract one fileMay require unpacking earlier solid data firstProgress has to be folder-aware.
Read metadata onceHeaders can be stored in compressed streamsCStreamSwitch keeps parsing state alive.
Write bytes to diskBytes arrive through callbacks with CRC checksCFolderOutStream keeps output honest.
Embed a libraryLegacy COM-like interfaces still shape the APIThe wrapper narrows the surface without rewriting the core.

The implementation style is old-school on purpose. It uses COM-like macros such as `MY_UNKNOWN_IMP1`, avoids external dependencies, and leans on the Windows API directly. That buys a narrow integration surface and keeps the code portable within Windows environments, but it also preserves the dense, C-style C++ that made 7-Zip both powerful and intimidating.

This is the trade-off of the project. You get a proven decompression engine wrapped in a friendlier DLL surface, but you still inherit the same architectural gravity that has always made 7-Zip hard to reason about at a glance. The repo feels like a targeted utility from a single maintainer, which usually means fewer abstractions, faster decisions, and a bigger burden on whoever has to read the code next.