msi — guide
Class:
guide· audience: a techie packaging a Windows product. The what is inmsi-design.md.
Describe the Windows product
use skidbladnir::msi::{WindowsComponentSpec, WindowsServiceSpec, ServiceStart, WixFile};
let spec = WindowsComponentSpec {
name: "holger".into(),
display_name: "Holger".into(),
version: "0.1.5".into(),
upgrade_code: "…stable-upgrade-code…".into(),
install_dir: r"C:\Program Files\Nordisk\Holger".into(),
service: WindowsServiceSpec {
account: "LocalSystem".into(),
start: ServiceStart::Auto,
delayed: true,
env_block: vec![("HOLGER_DATA".into(), r"C:\ProgramData\Holger".into())],
},
files: vec![WixFile { source: "holger.exe".into(), id: "holgerexe".into() }],
};
Render the WiX source (no tooling needed)
let wxs = skidbladnir::msi::render_wxs(&spec); // pure — a real Product.wxs string
// each file carries a stable component GUID; the service block is registered
Mint a stable component GUID
let g = skidbladnir::msi::component_guid("holger-main-exe"); // same id → same GUID, every build
Stable GUIDs are what make MSI upgrades (not side-by-side installs) work — never randomize them.
Build the MSI (needs podman + the WiX-in-Wine image)
use skidbladnir::msi::WixBuilder;
let builder = WixBuilder::new("registry/nordisk/wix-wine:4");
if builder.podman_available() {
builder.build(&spec, std::path::Path::new("holger.msi"))?;
} else {
// build() would bail with a clear message and leave the rendered WXS staged for inspection
}
Gotchas
WixBuilderis gated on podman at runtime, not a cargo feature — a machine without podman gets an honest error (and the staged WXS), never a fake.msi.- The
upgrade_codeand every component GUID must be stable across versions — that is how Windows recognizes an upgrade of the same product.guid_v5guarantees stability from the id.