Windows Code Signing & Installer Creation with InnoSetup

Hey everyone,

I’m excited to share GitHub: jo-tools/ats-codesign-innosetup – an open-source project that makes Windows Code Signing and Installer Creation (with InnoSetup) easier than ever.

Key Features

  • Windows Code Signing
    Sign your Xojo built Windows executables and created Installers using either
  • Seamless InnoSetup Integration
    Automates the entire process after compilation from signing to packaging.
    You just have to click “Build” in the Xojo IDE.
  • Cross-Platform Support
    Works with the Xojo IDE running on Windows, Linux, and macOS - allowing you to build and sign your Windows applications and installers from any OS.
  • Minimal Setup
    No complex installation and dependencies—just Docker is required.

Why Check It Out?

If you’ve ever struggled with code signing or setting up a reliable Windows installer, this project can save you time and hassle. Whether you’re an independent developer or working on a team, this solution helps streamline the process with minimal setup.

Take a look at the project on GitHub: jo-tools/ats-codesign-innosetup.
The ReadMe has all the details to get started.

I’d love to hear your thoughts!
Feel free to try it out and share your feedback or questions here or on GitHub.

20 Likes

Wow.

2 Likes

Thank you for the share, did not make any progress regarding manually doing it. Will try it soon !

For other that are using InnoSetup but don’t need the codesigning example there might be something else of interest in the example project.

It’s using a single InnoSetup Script innosetup_universal.iss for all Build Targets (Win32, Win64, ARM64). You’ll see conditionals in there, e.g.:

#if defined(csBuildTargetWIN32)
  ...
#elif defined(csBuildTargetWIN64)
  ...
#elif defined(csBuildTargetARM64)
  ArchitecturesInstallIn64BitMode=arm64
  ArchitecturesAllowed=arm64
#endif

This allows calling InnoSetup with corresponding parameters to use the same .iss, but get different output depending on the parameters.

I have tried to make it even so universal that also App Name, Company Name, Executable Name, … are being set via Parameters (read from the Xojo Project from the Post Build Script). So I can use this very same .iss script for many/different Xojo Projects without any modification.

Just copy both .iss and Post Build Script into another project and auto-magically get a windows installer created (well, Docker is required of course).

1 Like

I’ve just released v.1.2.0 of GitHub: jo-tools/ats-codesign-innosetup – an open-source project that makes Windows Code Signing and Installer Creation (with InnoSetup) easier than ever.

It addresses a potential security concern and shows how to integrate a secret storage in a x-platform way into the Xojo Post Build Scripts.

Instead of having a codesigning credential stored in a configuration file it will be retrieved from the secret storage and passed to the Docker Container via Environment Variable.

The Xojo Example Project includes an example which supports:

  • macOS: Keychain
  • Linux: Gnome Keyring
  • Windows: Windows Credential Manager

Take a look at the project on GitHub: GitHub: jo-tools/ats-codesign-innosetup.
The ReadMe has all the details to get started.


And btw: All the included Post Build Scripts can be used individually.
So you could just use the InnoSetup step, but without CodeSign - in case you just want to create a Windows Installer for your Xojo Desktop Project, but aren’t codesigning your Windows executables (yet).

7 Likes

Finally had time to try it out.

Work like a charm with the command line. I will look at the build stages and specially the innosetup one, I already have an innosetup file configured and would like to pass it to the build step

Thank you

1 Like

This looks amazing! I need this capability and yesterday I was part way through installing Crossover/Wine and InnoSetup plus the .issc script, a script to start InnoSetup in Wine and finally a Xojo build script to automate building an installer for the Windows version of my app on OSX.

Jürg this looks like the perfect alternative. I have only the barest docker experience but I’m going to give this a try today. Thank you so much for providing not only these tools but especially for the amazingly thorough and clear documentation. Very rare combination indeed!!!

1 Like

I don’t like messing up my machines with a lot of custom installation and setup :wink:
That’s why I’m using Docker for these kind of things… it’s all self-contained, and one can get rid of it with a simple deletion of a container/image. Or update to using a newer version of some container/image.

In theory it should be as simple (on macOS) as downloading Docker Desktop and running it.
Then follow the steps in the GitHub project’s ReadMe. For just InnoSetup (without CodeSigning) it’s basically just copying the folder _build (with the “universal innosetup script”) to the Xojo Project location and adding a Post Step Script (by copy-pasting from the example project).

Klick “build” in Xojo - and have a Windows Installer created auto-magically.
The first build will take a while (since it’s downloading the Docker Image) - next builds will use the now locally available Docker Image without needing to download again.

From there one can of course start modifying the .iss script and/or PostBuild Script according to own custom needs.

Let us know how it works for you :slight_smile:

I can only tell from my experience that I’ve used this (without any modification) in several of my example projects that are available on GitHub successfully.

I’m well aware this doesn’t necessarily mean it works for everyone - so I’m curious to read if that helps other developers and projects.

Thanks - and you’re welcome. I’ve benefited from other OpenSource projects myself, so I’m happy to give something back. A (hopefully) good documentation is for both myself to remember how things work - and hopefully for others to use these projects without hassle. Especially since I’m not a company and not officially providing support (but try to help every now and then).

1 Like

LOL, that’s so true!

I’m also not very familiar with actually using GitHub other than downloading individual files. So it took me some time to gather all the separate pieces of the Xojo demo project. So I’ve got your docker image installed and have successfully built a Windows installer of your sample app. It seems straightforward to next copy and update the files you mention above over to my Xojo project. Thanks again for pulling this all together for the community!

Next time just download the whole project as .zip:

2 Likes

Thanks for the tip. Yes downloading the zip would have been a better approach. I use single file binary Xojo projects myself so I wasn’t anticipating needing so many separate files from GitHub. I do have GitHub Desktop but I wasn’t sure if I should Clone or Branch your repo to get all the files without risking unintended changes.

You’ll want to Clone to get a copy of the repository. When you’re ready to make changes that’s when you Branch :slight_smile:

3 Likes

Hi Jürg

I moved the .issc file to my project folder and created the post-build step with the script from your demo project. Things are starting to come alive nicely and I get this message. It also complains in the same way if Stage is set to Alpha.

If Stage is set to Beta I get this.

It does then proceed to create a working installer. Success!!!

I may see if I can comment out that last warning message. My project is for use by a very small group of internal folks so I’m not currently planning to do code signing.

Read the comments in the script and adjust to your needs.
You’re seeing the default behavior (e.g. no installer for development builds). That’s easy to change and adjust if you want that.

There are also Booleans to suppress these messages. To get started I think they are helpful - once you have configured your desired settings you might want to change to the ‘silent’ behavior or comment out some of these informational messages.

Yay..!

1 Like

Jürg

Not surprisingly this requires Docker to already be running before doing the Xojo build. Is it feasible that the Build script could check if Docker is already running and start it as needed?

Thanks,
Joe

Of course.
You can configure Docker to be started always:

It does that already - checking it. I don’t think it’s a good idea to try launch it from there, from within a Xojo process (but feel free to try and add this feature in your own project’s build script).

That’s in the Post Build Script - it checks and reports if Docker is not available/running:

'bVERYSILENT=True : don't show any messages at all - even if Docker not Available or InnoSetup errors
Var bVERYSILENT As Boolean = False 'in this example project we want to show if it's not going to work
[...more script code...]
If (iCHECK_DOCKER_RESULT <> 0) Then
    If (Not bVERYSILENT) Then Print "InnoSetup: Docker not running"
    Return
End If

And that’s why the example project has enabled all these output by default :wink:

In your case (since you don’t do codesigning) I would suggest to

  • modify the script according to your needs (e.g. enable creating an installer for Development/Alpha builds, if that’s what you want) - simply comment out the lines within the switch statement:
'(Modified) -> DO create Windows Installer for Development and Alpha Builds
Select Case PropertyValue("App.StageCode")
    Case "0" 'Development
        // If (Not bSILENT) Then Print "InnoSetup: Not enabled for Development Builds"
        // Return
    Case "1" 'Alpha
        // If (Not bSILENT) Then Print "InnoSetup: Not enabled for Alpha Builds"
        // Return
    Case "2" 'Beta
    Case "3" 'Final
End Select

Then:

  • only comment out the print Info about the “Proceeding without codesigning the windows installer”
    (you intentionally don’t want to see this info every time)
If (Not bCODESIGN_ATS) And (Not bCODESIGN_PFX) Then
	// If (Not bSILENT) Then Print "InnoSetup: [...] Proceeding without codesigning the windows installer"
    bCODESIGN_AVAILABLE = False
Else
    bCODESIGN_AVAILABLE = True
End If

I’m curious what your concerns would be with doing this?

I will need to make Windows installers only a few times a year, so I don’t want to leave Docker running full-time. And I’d rather not have to remember to start it before making a Xojo build of this app.

1 Like

Partly personal preference. And it’s a bit tricky in a x-platform way.
I don’t like to idea of doing too much detection in a “simple” example project/script, as it’s providing the basic approach and can be enhanced oneself for custom needs.


Anyway, I’ve pushed an approach to a Feature Branch, which might make it into the Main Branch and a Release sooner or later.

Meanwhile you can replace the section in the Post Build Script which tries to detect if Docker is running with this:

Var sCHECK_DOCKER_PROCESS As String = DoShellCommand(sDOCKER_EXE + " ps", 0, iCHECK_DOCKER_RESULT).Trim
If (iCHECK_DOCKER_RESULT <> 0) Then
  'Try to launch Docker (wait max 30 seconds)
  If TargetWindows Then 'Xojo IDE is running on Windows
    Call DoShellCommand("""C:\Program Files\Docker\Docker\Docker Desktop.exe""")
    Call DoShellCommand("powershell -Command ""$i=0; while (-not (docker ps 2>$null)) { Start-Sleep -Seconds 1; $i++; if ($i -ge 30) { exit 1 } }""")
  ElseIf TargetMacOS Then 'Xojo IDE is running on macOS
    Call DoShellCommand("open -b com.docker.docker", 0)
    Call DoShellCommand("sleep 5") 'give it a bit of time to start launching
    Call DoShellCommand("i=0; while ! " + sDOCKER_EXE + " ps >/dev/null 2>&1; do sleep 1; i=$((i+1)); if [ $i -ge 25 ]; then exit 1; fi; done")
  ElseIf TargetLinux Then 'Xojo IDE is running on Linux
    // Not implemented
    ' Too many possible and different environments and ways to launch
    ' Implement yourself in a way that works for you machine setup
  End If
  'Re-check after trying to launch Docker
  sCHECK_DOCKER_PROCESS = DoShellCommand(sDOCKER_EXE + " ps", 0, iCHECK_DOCKER_RESULT).Trim
  If (iCHECK_DOCKER_RESULT <> 0) Then
    If (Not bVERYSILENT) Then Print "InnoSetup: Docker not running"
    Return
  End If
End If

This should work for both macOS and Windows (with a default Docker Desktop setup).
Just before that we already check if Docker is installed at all. If yes (but not currently running) - then this updated version tries to launch Docker from within the Xojo Post Build script before proceeding (or aborting - if that try-to-launch-docker fails, too).

1 Like

Thanks for coming up with this alternative so quickly. I’m having mixed results…

After adding your revised code, my first attempt to build without docker running hung for quite a long time (much longer than 30 sec) and finally a dialog saying a shell command failed and there is info in the clipboard. The clipboard held:

docker: error during connect: Post "http://%2FUsers%2Fjoehuber%2F.docker%2Frun%2Fdocker.sock/v1.49/containers/create": EOF

Run 'docker run --help' for more information

I started Docker Desktop myself, built again and it worked.

I quit Docker desktop, built again and it now starts up Docker desktop and the build works. I’ve done this multiple times and it’s working fine. I have no idea why the first time didn’t work though.

I’ve seen that once, too.

While in theory it should work, it does add (unnecessary?) complexity to the Post Build Script.
Letting it “manage” to start Docker itself requires all Xojo, Xojo’s Shell (the “not so often used one” in Post Build environment), macOS and Docker.app to play nice together.

Definitely hard to track down issues. It could be because of Docker.app not always playing nice with being opened via CommandLine, could be some weird macOS behavior - and the worst part: it could break with any macOS, Docker.app and/or even Xojo.app update.

One variation you could try is to combine the “opening” and “waiting a bit” in a single DoShellCommand. It’s a blind guess that maybe the Xojo Shell is quitting too fast for that kind of “opening another app”:

Call DoShellCommand("open -b com.docker.docker ; sleep 5", 0) 'give it a bit of time to start launching

Somehow it seems to me that the lesser evil might be to not add this to the official GitHub repository (or at least not yet, in it’s current not-always-reliable state). It doesn’t hurt a developer too much to get a Popup saying that “Docker is not running”, having to click 2x on Build in Xojo. If someone is doing builds with that Docker approach daily, then it’s likely more convenient to have Docker always running.

I guess it boils down to personal preference. I hope the basic idea of how to add that “launch Docker on the fly” is helpful to you. And should it turn out to not be reliable and be more of a hassle, then maybe switch back to the info message for now.

Let’s wait and see how this is behaving - or if someone finds another way to make this more reliable.


At least it seems that GitHub: jo-tools/ats-codesign-innosetup has proven to work for other people’s project too (with minimal effort - yay!). I’m glad it serves it’s purpose to help others for an easy way of adding Windows Installer creation to Xojo projects without too much hassle, and with minimal installation of other tools required.