WiX: Digitally Sign BootStrapper project
For me using WiX's in-built tool insignia
is the most straight-forward. Here's the steps I made to do code-sign a WiX MSI and bootstrap installer:
(steps 1 & 2 are just set up to make 3 & 4 read easy and more reusable and updatable! Steps 3 & 4 are the actual signing)
- Set up the
signtool
as a batch file in my PATH so that I can call it and change it easily. I'm running Windows 10 and so my "signtool.bat" looks like this:"c:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" %*
- Set up
insignia
as a batch file in my PATH too so you can change it with new WiX builds as they come. My "insignia.bat" looks like this:"C:\Program Files (x86)\WiX Toolset v3.10\bin\insignia.exe" %*
- Sign my MSI in a post-build event (MSI Project -> Properties -> Build Events) by calling this:
signtool sign /f "c:\certificates\mycert.pfx" /p cert-password /d "Your Installer Label" /t http://timestamp.verisign.com/scripts/timstamp.dll /v $(TargetFileName)
Sign my bundle in a post-build event for the bootstrap project like this:
CALL insignia -ib "$(TargetFileName)" -o engine.exe
CALL signtool sign /f "c:\certificates\mycert.pfx" /p cert-password /d "Installer Name" /t http://timestamp.verisign.com/scripts/timstamp.dll /v engine.exe
CALL insignia -ab engine.exe "$(TargetFileName)" -o "$(TargetFileName)"
CALL signtool sign /f "c:\certificates\mycert.pfx" /p cert-password /d "Installer Name" /t http://timestamp.verisign.com/scripts/timstamp.dll /v "$(TargetFileName)"
Further notes and thoughts:
I have also signed the application (I think) by just doing
Project Properties -> Signing
and enabling click-once manifests, selecting the certificate and checking theSign the assembly
option.Specifying CALL is necessary in post-build events when calling a batch file or only the first one gets called.
<Target Name="UsesFrameworkSdk">
<GetFrameworkSdkPath>
<Output TaskParameter="Path" PropertyName="FrameworkSdkPath" />
</GetFrameworkSdkPath>
<PropertyGroup>
<Win8SDK>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0@InstallationFolder)</Win8SDK>
</PropertyGroup>
</Target>
<Target Name="UsesSignTool" DependsOnTargets="UsesFrameworkSdk">
<PropertyGroup>
<SignToolPath Condition="('@(SignToolPath)'=='') and Exists('$(FrameworkSdkPath)bin\signtool.exe')">$(FrameworkSdkPath)bin\signtool.exe</SignToolPath>
<SignToolPath Condition="('@(SignToolPath)'=='') and Exists('$(Win8SDK)\bin\x86\signtool.exe')">$(Win8SDK)\bin\x86\signtool.exe</SignToolPath>
</PropertyGroup>
</Target>
<Target Name="SignBundleEngine" DependsOnTargets="UsesSignTool">
<Exec Command=""$(SignToolPath)" sign /d "App Setup" /t http://timestamp.digicert.com /a "@(SignBundleEngine)"" />
</Target>
<Target Name="SignBundle" DependsOnTargets="UsesSignTool">
<Exec Command=""$(SignToolPath)" sign /d "App Setup" /t http://timestamp.digicert.com /a "@(SignBundle)"" />
</Target>
This works well for me. Either you do it during the build, or you need to use insignia.
Ex:
http://wixtoolset.org/documentation/manual/v3/overview/insignia.html
insignia -ib bundle.exe -o engine.exe
... sign engine.exe
insignia -ab engine.exe bundle.exe -o bundle.exe
... sign bundle.exe