ISApexEx v0.1 beta
Unified Archive Extraction & Xdelta3 Patching API for Inno Setup
7-Zip · FreeArc · RAR · Xdelta3 one DLL · Win32 · by BLACKFIRE69
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━
▌ OVERVIEW
ISApexEx is a high-performance unified library crafted for Inno Setup. It integrates
four engines
7-Zip,
FreeArc,
RAR, and
Xdelta3 into a single DLL with seamless cross-format progress tracking. Mix and match
.7z, .zip, .arc, .bf, .rar and xdelta3 patch operations in one installer with continuous progress across all of them.
▌ TECHNICAL SPECIFICATIONS- Version v0.1 beta
- Author BLACKFIRE69
- Build 6A20C000
- File Size 291 KB
- Compatibility Inno Setup v6.0 or later (Required)
Code:
╭──────────┬──────────┬──────────────────────┬─────────────────────────────╮
│ Engine │ Version │ Native DLL │ Supported Extensions │
├──────────┼──────────┼──────────────────────┼─────────────────────────────┤
│ 7-Zip │ v26.10 │ 7z_32.dll │ .7z, .zip, .7z.001/.002... │
│ FreeArc │ v0.67 │ UnArc_32.dll │ .arc, .bf... │
│ UnRAR │ v7.22 │ UnRAR_32.dll │ .rar, .part01.rar... │
│ xdelta3 │ v0.1 │ xdelta3_wrapper.dll │ .xd3, .xdelta, .vcdiff... │
╰──────────┴──────────┴──────────────────────┴─────────────────────────────╯
Disk-spanning (FreeArc 'diskspan' volumes setup-1.bin, setup-2.bin
): handled by
cls-diskspan v2.0 (modified edition)
natively no ClsFunc* calls needed from your script.
▌ KEY FEATURES
✦ Unified Multi-Format Support
Handle .7z, .zip, .arc, .bf, .rar and xdelta3 patches from one DLL. Format is auto-detected from the file extension no manual engine selection.
✦ Top-Level AND Split / Multi-Volume Support
Every format extracts both as a single top-level archive and as a split set: 7z split volumes (.7z.001
), RAR multi-volume (.partNN.rar / .rNN), FreeArc disk-span volumes. Parts may even be scattered across different folders or discs.
✦ Universal File Browsing (Locate a Missing Archive or Part)
When ISApexEx can't find a file it needs a top-level archive of ANY format, a 7z split part, a RAR volume, or a FreeArc spanned volume it lets the user locate it, then resumes. Built-in native browse dialog, or your own themed dialog via
ISApexExSetDiskRequestCallback (one callback covers every case).
✦ Lazy DLL Loading
Only the native engine DLLs actually needed are loaded at runtime. Using only .7z and .rar? UnArc_32.dll and xdelta3_wrapper.dll are never touched.
✦ Cross-Format Progress
Overall progress (01000) spans all registered disks regardless of format. A mixed .arc + .7z + .rar + xdelta3 setup shows one smooth, continuous bar.
✦ Custom Extension Mapping
Archives don't have to use standard extensions map any extension to any engine via
ISApexExRegisterExtension before adding disks.
Code:
ISApexExRegisterExtension('.bin', APEX_ARC_7Z); // .bin -> 7z engine
ISApexExRegisterExtension('.cp', APEX_ARC_ARC); // .cp -> FreeArc engine
ISApexExRegisterExtension('.dat', APEX_ARC_RAR); // .dat -> RAR engine
✦ Advanced Progress Tracking
Real-time Overall Progress, Current Disk Progress, and Extracted/Total File Counts.
✦ Performance Metrics
Accurate Current and Average Speed (MB/s).
✦ Time Management
"Time Remaining" + "Elapsed Time" with three display formats (
00:00:00 /
x hr y min /
x hours y minutes).
✦ Process Control
Suspend, Resume, or Stop the extraction safely at any point.
✦ UI Stability
"Calc Accuracy" reduction logic prevents erratic jumping in speed and ETA displays.
✦ Localization
Switch languages at runtime via external .ini files. Ships with English and Russian.
✦ Event Callback System
Optional callback fires on discrete lifecycle events engine loaded, disk started/finished/failed, error, all done. Great for logging and diagnostics.
✦ File-Based Logging
Thread-safe logging with configurable verbosity (Off, Error, Info, Verbose).
✦ Thread Priority Control
Set extraction thread priority before each disk (Idle
Highest).
✦ Disk Space Pre-Check
Verify free space on the output drive before extraction per-disk or all disks at once.
✦ Progress Persistence / Resume (Crash Recovery)
On a crash (power loss, kill, BSOD) the library has saved state after each disk; on relaunch
ISApexExLoadResume validates and restores progress, already-done disks are skipped. CRC32-checked, auto-deleted on success, fully opt-in (zero overhead unless
ISApexExSetResumeFile is called).
▌ ENGINE FEATURES
◆ 7-Zip
Normal + split archives (.7z.001
), ZIP via the same engine, password-protected archives. The 7-Zip API requires split parts to be merged first, so ISApexEx builds a local temp file. Single directory → auto-detected; parts spread across folders → set the total with
ISApexExSetSplitPartCount; override the temp location with
ISApexExSetSplitTmpPath.
◆ FreeArc
Normal .arc/.bf, selective folder extraction (
ISApexExAddDisksEx), external processor integration (SREP, XTool, LOLZ, NZ, RZ
), config file + work path (
ISApexExExtractEx), password-protected archives, and native disk-span support via cls-diskspan v2.0 when a volume is missing, the user is prompted to locate it and extraction resumes. Ship cls-diskspan.dll next to ISApexEx.dll; no ClsFunc* calls needed.
◆ RAR
Normal + multi-volume archives (.part01.rar
) with automatic volume switching (no extra API calls), password-protected archives.
◆ Xdelta3 Patching- Single-file patching ISApexExAddPatch(PatchFile, SourceFile, OutputFile)
- Batch directory patching ISApexExAddPatchDir(PatchDir, SourceDir, OutputDir, Pattern)
- In-place patching when source = output, done via a temp file (decode to .xd3tmp, delete original, rename)
- User-defined patch extensions Pattern controls the scanned extension: *.xd3 (default), *.patch, *.delta, *.myext
- Recursive directory scanning batch mode searches subdirectories
- Deferred listing patch/source dirs are scanned at extraction time, so you can patch files produced by an earlier archive in the same installer
- Interleaved workflow extract archives and apply patches in any order; progress stays continuous
▌ SUPPORTED FILE STRUCTURES
Code:
[ROOT]
├── data1.7z (normal 7z archive)
├── data2.zip (ZIP archive via 7z engine)
├── Disks/
│ ├── Disk1/
│ │ ├── Sonic 2.7z.001 (split 7z, parts across directories)
│ │ └── Sonic 2.7z.002
│ └── Disk2/
│ ├── Sonic 2.7z.003
│ └── Sonic 2.7z.004
├── data3.arc (FreeArc archive)
├── data4.bf (FreeArc archive)
├── data5.part01.rar (multi-volume RAR)
├── data5.part02.rar
├── data5.part03.rar
├── data6.rar (normal RAR archive)
├── setup-1.bin (cls-diskspan archive)
├── data7_xdelta.bin (archive containing xdelta3 patches)
└── Setup.exe
▌ SUPPORTED FILE EXTENSIONS
Code:
╭────────────────────────────┬──────────────────┬──────────────────╮
│ Extensions │ Engine │ Constant │
├────────────────────────────┼──────────────────┼──────────────────┤
│ .7z .7z.001 .7z.002 ... │ 7z engine │ APEX_ARC_7Z │
│ .zip │ 7z engine │ APEX_ARC_7Z │
│ .arc .bf │ FreeArc engine │ APEX_ARC_ARC │
│ .rar .r00 .r01 ... │ RAR engine │ APEX_ARC_RAR │
│ .xd3 .xdelta .vcdiff ... │ xdelta3 engine │ APEX_ARC_XDELTA │
╰────────────────────────────┴──────────────────┴──────────────────╯
▌ EXPORTED API FUNCTIONS- Initialization ISApexExInit, ISApexExInitEx
- Disk Registration ISApexExAddDisks, ISApexExAddDisksEx, ISApexExAddPatch, ISApexExAddPatchDir, ISApexExRegisterExtension, ISApexExClearExtensions
- Extraction ISApexExExtract, ISApexExExtractEx
- Process Control ISApexExSuspendProc, ISApexExResumeProc, ISApexExIsSuspended, ISApexExStop
- Progress & Metrics ISApexExGetTotalSizeMBOfAllDisks, ISApexExGetExtractedSizeMBOfAllDisks, ISApexExCallbackInterval, ISApexExGetCallbackInterval, ISApexExReduceCalcAccuracy
- Configuration ISApexExChangeLanguage, ISApexExSetSplitPartCount, ISApexExSetSplitTmpPath, ISApexExSetThreadPriority, ISApexExCheckFreeSpace, ISApexExCheckAllFreeSpace
- Logging & Events ISApexExSetLogFile, ISApexExSetLogLevel, ISApexExSetEventCallback
- File Browsing ISApexExSetDiskRequestCallback (global covers every format + missing-part case)
- Resume / Crash Recovery ISApexExSetResumeFile, ISApexExLoadResume, ISApexExHasResume, ISApexExClearResume
▌ QUICK START EXAMPLES
Example 1 Mixed Archives (7z + FreeArc + RAR)
Code:
#include "ISApexEx.iss"
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if not AddArchiveEntry('data1.7z') then Exit;
if not AddArchiveEntry('data2.bf') then Exit;
if not AddArchiveEntry('data3.rar') then Exit;
if ISApexExInitEx(2, @ProgressCallbackEx) then
begin
for i := 1 to ISApexExDiskCount do
if not ISApexExExtract(i) then Break;
ISApexExStop;
end;
end;
end;
Example 2 Extract + xdelta3 Batch Patching
Code:
if not AddArchiveEntry('data1.7z') then Exit; // base archive
if not AddArchiveEntry('data_xdelta.rar') then Exit; // sources + patches
// apply all *.xd3 in \patches to sources in \modified -> \rebuilt
ISApexExAddPatchDir(
ExpandConstant('{app}\patches'),
ExpandConstant('{app}\modified'),
ExpandConstant('{app}\rebuilt'),
'*.xd3');
ISApexExDiskCount := ISApexExDiskCount + 1;
Example 3 Single File xdelta3 Patch (In-Place)
Code:
if not AddArchiveEntry('data1.7z') then Exit; // contains original game.exe
// patch game.exe in-place using game.exe.xd3
ISApexExAddPatch(
ExpandConstant('{src}\game.exe.xd3'),
ExpandConstant('{app}\game.exe'),
ExpandConstant('{app}\game.exe'));
ISApexExDiskCount := ISApexExDiskCount + 1;
Example 4 Split 7z Archive (Multi-Part .7z.001/.002/
)
Code:
if not AddArchiveEntry('Sonic 2.7z.001') then Exit;
// parts spread across folders: declare total count + a temp path
ISApexExSetSplitPartCount(ISApexExDiskCount, 7);
ISApexExSetSplitTmpPath(ISApexExDiskCount, ExpandConstant('{src}'));
Example 5 Split RAR Archive (Multi-Volume .part01.rar/
)
Code:
if not AddArchiveEntry('data1.7z') then Exit;
// just pass the first part UnRAR switches volumes automatically
if not AddArchiveEntry('data3.part01.rar') then Exit;
Example 6 Progress Persistence / Resume (Crash Recovery)
Code:
ISApexExSetResumeFile(ExpandConstant('{src}\ISApexEx.resume'));
if ISApexExInitEx(2, @ProgressCallbackEx) then
begin
if ISApexExLoadResume then // prompts Yes/No to resume
Log('Resuming from previous session');
for i := 1 to ISApexExDiskCount do // done disks are skipped
if not ISApexExExtractEx(i, cfg, tmp) then Break;
ISApexExStop; // auto-deletes resume file on success
end;
Example 7 Global "Locate Missing Archive / Volume / Part" Dialog
One callback handles EVERY case: a missing top-level archive of any format, a 7z split part, a RAR volume, or a FreeArc spanned volume. Runs on the main thread (MsgBox / GetOpenFileName / a custom TForm are all safe). Omit it to use the built-in native browse.
Code:
function MyDiskRequest(const Filename, CurrentDir: WideString): WideString;
begin
if MsgBox('Please insert / locate: ' + Filename,
mbConfirmation, MB_OKCANCEL) = mrCancel then
begin
Result := ''; // cancel -> clean user-abort
Exit;
end;
// ... GetOpenFileName, or your own themed TForm ...
Result := PickedFolder; // the folder that now holds Filename
end;
// register once, after Init, before Extract:
ISApexExSetDiskRequestCallback(@MyDiskRequest);
▌ DISTRIBUTION FILES- ISApexEx.dll Unified API library (single DLL for all four engines)
- ISApexEx.iss Header for Inno Setup (types, constants, imports)
- 7z_32.dll 7-Zip engine (.7z/.zip)
- UnArc_32.dll FreeArc engine (.arc/.bf)
- UnRAR_32.dll UnRAR engine (.rar)
- xdelta3_wrapper.dll xdelta3 engine (patching)
- cls-diskspan.dll (Optional) FreeArc disk-spanning plugin, v2.0 modified edition. Only for setup-N.bin sets.
- English.ini / Russian.ini Language files
- arc.ini / CLS.ini FreeArc external-processor configuration
Engine DLLs are lazy-loaded ship only the ones the archives you use actually need.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━
Feedback, bug reports, and edge cases are all welcome.
.