Signing packages and bundles
Signing Windows Installer packages
Windows Installer packages can be signed directly by signing tools like Signtool.exe. However, you can also sign cabinets that are external to the .msi file and include those signatures in the .msi so Windows Installer can verify that the cabinets haven't been tampered with.
If you're including MSI packages with external cabinets in a Burn bundle, it is not necessary to sign the cabinets. Instead, sign the bundle; the bundle includes a manifest that contains hashes for every file in the bundle. The bundle's signature ensures the validity of the manifest and Burn securely verifies the included hashes.
If you're embedding the cabinets in their MSI package, signing them is not necessary; just sign the MSI package instead. The signature on the MSI package includes the embedded cabinets.
Signing packages with MSBuild
To enable signing, set the SignOutput
property to true
:
<PropertyGroup>
<SignOutput>true</SignOutput>
</PropertyGroup>
To sign external cabinets, create a SignCabs
target in your .wixproj to call your signing tool:
<Target Name="SignCabs">
<Message Importance="high" Text="SignCabs: @(SignCabs)" />
<Exec Command='signtool.exe sign /v /f $(TestCertificate) /p password %(SignCabs.FullPath)' />
</Target>
To sign the MSI package, create a SignMsi
target in your .wixproj to call your signing tool:
<Target Name="SignMsi">
<Message Importance="high" Text="SignMsi: @(SignMsi)" />
<Exec Command='signtool.exe sign /v /f $(TestCertificate) /p password "%(SignMsi.FullPath)" ' />
</Target>
The SignMsi
target updates the MSI package with the signature information of any detached cabinets, then invokes your commands to do the signing.
Signing packages at the command-line
The Wix.exe command-line tool lets you update the MSI package with the signature information of any detached cabinets. Signing the cabinets and the MSI package itself is left to your build tooling of choice.
To update an MSI package with the signatures of detached cabinets:
wix msi inscribe path\to\package.msi -out path\to\inscribedpackage.msi
To update an MSI package in-place with the signatures of detached cabinets:
wix msi inscribe path\to\package.msi
Signing bundles
Signing bundles is slightly more complicated than signing packages because bundles need to be signed in two pieces:
- The Burn engine, along with the bundle manifest and bootstrapper application, is extracted and cached for repair and uninstall operations. It needs to be signed so that those operations present the user with a "friendly" UAC consent prompt that identifies the bundle and signature.
- The whole bundle .exe file needs to be signed to ensure that a compressed bundle with embedded packages can be verified.
Signing bundles requires the following flow:
- Build the bundle.
- Extract the Burn engine from the bundle.
- Sign the Burn engine.
- Reattach the signed Burn engine to the bundle.
- Sign the whole bundle.
Signing bundles with MSBuild
To enable signing, set the SignOutput
property to true
:
<PropertyGroup>
<SignOutput>true</SignOutput>
</PropertyGroup>
To extract the Burn engine from the bundle, sign it, and reattach it, create a SignBundleEngine
target in your .wixproj to call your signing tool:
<Target Name="SignBundleEngine">
<Message Importance="high" Text="SignBundleEngine: @(SignBundleEngine)" />
<Exec Command='signtool.exe sign /v /f $(TestCertificate) /p password %(SignBundleEngine.FullPath)' />
</Target>
To sign the whole bundle, create a SignBundle
target in your .wixproj to call your signing tool:
<Target Name="SignBundle">
<Message Importance="high" Text="SignBundle: @(SignBundle)" />
<Exec Command='signtool.exe sign /v /f $(TestCertificate) /p password %(SignBundle.FullPath)' />
</Target>
Signing bundles at the command-line
To extract the Burn engine from the bundle:
wix burn detach path\to\bundle.exe -engine path\to\extracted\burnengine.exe
Then sign path\to\extracted\burnengine.exe.
To reattach the signed Burn engine to the bundle:
wix burn reattach path\to\original\bundle.exe -engine path\to\extracted\burnengine.exe -o path\to\full\bundle.exe
Then sign path\to\full\bundle.exe.