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.
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).
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:
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).
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
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!!!
I don’t like messing up my machines with a lot of custom installation and setup
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
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).
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!
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.
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.
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.
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?
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
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.
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).
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.
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.