Gunnar

nordisk/Skidbladnir

.nornir/msi-guide.md

# msi — guide

> **Class:** `guide` · audience: a techie packaging a Windows product. The *what* is in
> [`msi-design.md`](msi-design.md).

## Describe the Windows product

```rust
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)

```rust
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

```rust
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)

```rust
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

- `WixBuilder` is 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_code` and every component GUID must be **stable across versions** — that is how
  Windows recognizes an upgrade of the same product. `guid_v5` guarantees stability from the id.