How To Sign Qt Apps on Windows for Release

How To Sign Qt Apps on Windows for Release

You just made your brand spanking new QT app, now how do you sign and deploy it on Windows?

A common tool for deploying QT applications on Windows is windeployqt, while that’s great for just deploying your app, how do you actually sign it?

windeployqt will then generate the appropriate binaries to allow execution of .exe files on the users machine. It does not however handle anything beyond that, which includes creating an installer and actually singing your app (so your users don’t get that scary warning popup 😬).

For the sake of completeness, let’s do a quick overview (or just skip to signing)

Packaging QT Windows Apps

Step 1 – Deploying (windeployqt)

To get started build a release version of you application. This will create the necessary files for the windeployqt tool. If you’re using Qt creator the default build folder is usually named build-…-Release/release. For ease of use you can add the windeployqt tool to your PATH so you can execute it directly in the /release folder (or just use the full path name). Though that might be a hassle, so you can just run it in the default build environment. Type Qt into the Windows search bar and see:

Select a build environment and you will have access to windeployqt in the console. Simply cd into the directory of your release build and run windeployqt:

cd C:\path-to-build\build-awesomeapp-stuff-Release\release

windeployqt appname.exe

This will create (copy) the necessary .dll files in your /release folder. Making the .exe runnable outside Qt creator (or if the user does not have Qt dlls in their path). You can just zip this folder and send it around and it should work (on the platform you build it for), if you would also like an installer continue to the next step otherwise skip to signing. On windows you can just sign the .exe if that’s all you want to distribute.

Step 2 – Installer (optional)

Installers are an optional step as you can directly sign the binaries, but are useful to the user if they want a clean install/uninstall of your app.

There’s quite a few ways to go about this. The general idea, however, stays the same. After deploying your Qt application to binaries you wrap them up in a neat installer.

Since we’re using Qt the first choice of installer would probably be the Qt Installer Framework. Personally, I have not had the greatest experience using Qt Installer Framework and found it way too cumbersome to customize. In my opinion a better option is Inno Setup which has the unfortunate limitation of only running on Windows.

Now moving on to the main topic at hand…

Step 3 – Signing

There’s in-depth documentation on the Microsoft docs about this. But here we’ll mainly focus on just getting your Qt app signed with the least hassle possible.

Okay, so how do you actually sign your application?

There’s two ways to go about it. You either sign the installer or directly sign the executable (if you do not want to include an installer). No matter your choice the first step will be the same, getting the certificate.

3.1 Certificate

You can directly buy a certificate from different CAs (Certificate Authorities) such as: DigiCert, Comodo, Sectigo… There’s a more in depth description about CAs and different vendors here.

If you want to avoid the SmartScreen popup, you will have to buy an EV certificate which is more expensive than a regular certificate. EV certificates can (usually) be used the same way as a normal certificate.

To keep things simple and free we’ll just generate our own certificate. This was usually done with Makecert, but since that has officially been deprecated we’ll use PowerShells New-SelfSignedCertificate instead. Do note that if you want to use self-signed certificates in production you will have to redistribute them to your customers, who will then have to install them manually. Therefore you should (preferably) only use self-signed certificates for testing.

To get started let’s create some certificates, run these commands (in an elevated powershell window):

$cert = New-SelfSignedCertificate -DnsName test.test.com -CertStoreLocation cert:\LocalMachine\My -Type CodeSigning

$pwd = ConvertTo-SecureString -String "password" -Force -AsPlainText

Export-PfxCertificate -cert $cert -FilePath cert.pfx -Password $pwd

This will generate a cert.pfx file which we will need to actually sign our application. Before we can sign it though, we need some tool to sign it with!

3.2 Sign binaries & most installer formats directly

If your installer of choice does not support SignTool please check the relevant documentation.

Before continuing make sure to install the Windows SDK which includes the SignTool. Once installed simply run the following command. You can sign installers and binaries the same way, the example below signs an .exe but is identical on .msi files. Simply run:

signtool.exe sign /f cert.pfx /p password /d app-description app.exe
  • /f Specifies the signing certificate in a file
  • /p Specifies the password to use when opening a PFX file
  • /d Specifies a description of the executable or installer of your app. This may also be displayed as a name in the UAC prompt (see image below).

For a detailed description of all arguments check the Microsoft documentation. Once the command has successfully executed the executable will now be signed!

Step 4 – Distribute

Once signed simply distribute the binares/installer to your client (if you’re using self signed certificates those will have to be distributed as well).