Dumplings.InstallerParsers provides process-isolated static parsers for Windows installer formats whose implementations use GPL-compatible licenses. It is consumed by Dumplings.PackageModule through a JSON command-line boundary.
The parsers inspect untrusted installer bytes through bounded reads. They return product metadata, scope, registry writes, associations, nested payload evidence, and structured diagnostics.
- Windows
- PowerShell 7.4 or later
- The pinned managed dependencies distributed with the submodule
The CLI loads only the requested family. Inno keeps format/catalog decoding, Pascal Script analysis, and payload extraction in nested InnoFormat, InnoScript, and InnoPayload modules. Setup Factory separates project records, action interpretation, and containers into SetupFactoryProject, SetupFactoryActions, and SetupFactoryContainer. Public commands stay in the original family modules. Nested commands are internal and are not added to the caller's global command table. Parsed contexts are passed explicitly, and each layer owns its streams and temporary resources.
Cli.ps1 is the stable integration boundary. It writes one compact JSON value to standard output, writes a failure message to standard error, and exits with code 0 on success or 1 on failure.
$Json = & pwsh -NoProfile -File .\Cli.ps1 `
-Action NSIS.GetInfo `
-Path C:\Installers\setup.exe
if ($LASTEXITCODE -ne 0) {
throw 'Installer parsing failed'
}
$Info = $Json | ConvertFrom-JsonExpansion actions return extracted paths or expansion evidence as JSON and always enforce parser-specific output limits:
& pwsh -NoProfile -File .\Cli.ps1 `
-Action NSIS.Expand `
-Path C:\Installers\setup.exe `
-DestinationPath C:\Analysis\NSIS `
-Name '*.msi' `
-ExternalDataPath C:\Installers\setup1.bin,C:\Installers\setup2.bin `
-CollisionAction Rename `
-MaximumExpandedBytes 1GBName is optional for every expansion action. Omitting it selects all catalogued files. The CLI defaults to non-interactive CollisionAction Rename (file (1).ext). Direct calls and interactive PackageModule bridge calls additionally accept Prompt. No question is shown until the parser encounters an existing or already-reserved output path. Interactive bridge calls inherit the parent console while returning JSON through a separate temporary result file. Paths are resolved against PowerShell's current filesystem location before crossing the JSON/.NET boundary.
Keep informational output off standard output to preserve the JSON contract. Return conditions through Diagnostics. Use the CLI error path only when an operation cannot return a valid result.
| Action | Purpose | Additional parameters |
|---|---|---|
NSIS.GetInfo |
Parse NSIS layout, commands, registry writes, payload evidence, and product metadata. | Path, optional Architecture, Scope |
NSIS.Expand |
Expand selected embedded or NSISBI external EW_EXTRACTFILE payload records from solid, non-solid, or MTW archives. |
Path, optional DestinationPath, Name, CollisionAction, ExternalDataPath, MaximumExpandedBytes |
NSIS.GetInstallerSwitchInfo |
Extract explicit command-line switch handling evidence. | Path |
NSIS.TestElectronBuilder |
Test whether the NSIS installer was generated by electron-builder. | Path |
NSIS.GetElectronBuilderInfo |
Parse electron-builder architecture, scope, and package evidence. | Path, optional Architecture |
Inno.GetInfo |
Parse Inno Setup metadata, registry writes, architecture, scope, and payload evidence. | Path, optional Architecture, IncludePascalScriptAnalysis, IncludeDisassembly, MaximumDisassemblyCharacters |
Inno.GetFormatInfo |
Identify the Inno edition, character mode, structure version, and selected parser routes. | Path |
Inno.GetPascalScriptInfo |
Parse compiled IFPS types, globals, functions, call edges, imports, constants, and manifest-relevant effects, with optional bounded disassembly. | Path, optional IncludeDisassembly, MaximumDisassemblyCharacters |
Inno.Expand |
Expand selected Inno payload files statically, including external disk slices supplied by the caller. | Path, optional DestinationPath, Name, Language, CollisionAction, DiskSourcePath, MaximumExpandedBytes |
AdvancedInstaller.GetInfo |
Parse the Advanced Installer bootstrapper catalog and nested MSI selection evidence. | Path |
AdvancedInstaller.Expand |
Expand catalog-selected payloads. | Path, optional DestinationPath, Name, CollisionAction |
QtInstallerFramework.GetFormatInfo |
Identify the Qt IFW generation, framework version, media role, capabilities, and selected parser routes. | Path |
QtInstallerFramework.GetInfo |
Parse Qt Installer Framework trailer, metadata, packages, operations, scope, and identity. | Path |
QtInstallerFramework.Expand |
Expand selected Qt IFW resources and archives. | Path, optional DestinationPath, Name, CollisionAction, MaximumExpandedBytes |
SetupFactory.GetInfo |
Parse Setup Factory 3.1 Crusher companion media, Setup Factory 4-10 outer and installed-file catalogs, Setup Factory 5/6 product and built-in uninstall blocks, Setup Factory 7-10 session variables, literal registry evidence, and bundled prerequisites. | Path |
SetupFactory.Expand |
Expand selected installed files, or outer bootstrap records with RawEntries. |
Path, optional DestinationPath, Name, RawEntries, CollisionAction, MaximumExpandedBytes |
The ValidateSet in Cli.ps1 is authoritative. Add a CLI action whenever a new public parser operation must cross the PackageModule boundary.
PackageModule (Apache-2.0)
InstallerBridge.psm1
|
| starts pwsh and exchanges JSON
v
InstallerParsers
Cli.ps1 (GPL-3.0-or-later)
+-- Libraries/Infrastructure (shared MIT mechanics)
`-- Libraries/Installers (one family loaded per action)
The CLI loads shared infrastructure before the selected parser:
Runtime.psm1loads pinned assemblies and auditable C# helpers once per process.Binary.psm1provides bounded reads, ranges, pattern search, CRC, and stream copying.FileSystem.psm1resolves PowerShell filesystem paths and rejects extraction-root escapes.Archive.psm1provides bounded compression, archive entry access, and extraction.PE.psm1resolves PE headers, sections, resources, overlays, and metadata.InstallerDiagnostics.psm1validates, merges, resolves, and renders structured parser diagnostics.InstallerEvidence.psm1evaluates bounded conditions and interprets explicit protocol and file-extension registry writes.- The selected format module constructs its canonical identity, ARP, and diagnostic result properties directly.
Shared MIT files remain file-level MIT exceptions in PackageModule. Full mirrored files stay byte-identical. The two shared filesystem helper function bodies also stay identical even though PackageModule's filesystem module contains additional task utilities. Format-specific code stays in its parser module.
- Identify formats from validated magic, headers, tables, resources, and registry records. Filename extensions and arbitrary strings are insufficient.
- Open the installer once per operation and pass bounded streams or parsed layouts to internal functions.
- Validate every offset, size, count, pointer, decompressed length, and extraction path before use.
- Preserve caller-owned stream position and ownership where a stream parameter is supported.
- Return context-neutral structured diagnostics for unresolved, conditional, unsupported, ambiguous, or invalid evidence.
- Keep
SuggestionsandSuggestedNextStepsfor actions. Do not encode actions as diagnostics. - Never invoke an installer, extracted executable, external extractor, or network endpoint.
Aggregate Get-*Info results begin with Path, InstallerType, ProductCode, UpgradeCode, DisplayName, DisplayVersion, Publisher, Scope, DefaultInstallLocation, WritesAppsAndFeaturesEntry, AppsAndFeaturesProductCode, AppsAndFeaturesInstallerType, Diagnostics, and UnresolvedFields. Results omit duplicate aliases such as ProductName and ProductVersion. The caller assigns diagnostic scenarios, levels, and blocking decisions with Resolve-InstallerDiagnostics, then renders them with Write-InstallerDiagnostics at the workflow boundary.
Detailed binary layouts and parser workflows live in the Dumplings analyze-winget-installer skill.
Add or change format behavior under Libraries/Installers. Mechanical operations that are useful to more than one parser belong in Libraries/Infrastructure and must be mirrored into PackageModule.
When adding a CLI action:
- Add it to
Cli.ps1'sValidateSet. - Import only the required parser in the action branch.
- Return a JSON-serializable object without incidental output.
- Add direct parser tests and PackageModule bridge contract tests.
- Document the action and its licensing.
From the Dumplings root:
Invoke-Pester .\Modules\InstallerParsers\TestsRun a focused parser suite:
Invoke-Pester .\Modules\InstallerParsers\Tests\NSIS
Invoke-Pester .\Modules\InstallerParsers\Tests\InnoAlso run PackageModule bridge tests after changing the CLI contract:
Invoke-Pester .\Modules\PackageModule\Tests\WinGet\InstallerBridge.Contracts.Tests.ps1
Invoke-Pester .\Modules\PackageModule\Tests\WinGet\InstallerBridge.Regressions.Tests.ps1Each implemented parser family owns one directory below Tests. Byte-identical fixture helpers and reusable generated-fixture builders live under non-discoverable Tests/Support. Downloaded fixtures use canonical paths below ../Dumplings-TestFixtures/Installers, curated media uses Builders, and synthetic or extracted output uses $TestDrive. Do not depend on user Downloads, temporary cleanup-sensitive paths, or executing installers.
Licensing is file-specific:
| Files | License |
|---|---|
Cli.ps1, Libraries/Installers/{NSIS,NSISFormat,NSISSimulation,Inno,QtInstallerFramework,SetupFactory}.psm1, Libraries/Installers/{NSIS,Inno,QtInstallerFramework,SetupFactory}FormatCatalog.psd1 |
GPL-3.0-or-later |
Libraries/Installers/AdvancedInstaller.psm1 |
GPL-2.0 |
Libraries/Infrastructure/{Runtime,Binary,FileSystem,Archive,PE,InstallerEvidence}.psm1 and shared infrastructure sources |
MIT, as marked in each file |
Third-party format references, included assemblies, and source-derived components are documented in Assets\THIRD-PARTY-NOTICES.md. The asset layout is described in Assets\README.md. Preserve file headers and license boundaries when moving or reusing code.