I had a software installer that needs to be distributed with its license key, but in a way that keeps the users safe from themselves, and us safe from auditors. Find out how I did this in about an hour with NSIS below…
The summary above really sums it all up nicely. A third-party vendor’s version of “volume licensing” is “here’s our installer, here’s a license file, put them both in the same directory and run the installer.” This makes it easy to mess up with non-technical users (what’s a zip file?) and hazardous for smarter users (I’ll just put this license file on TPB). In general, our users aren’t malicious, but why make it easy?
The Nullsoft Installer System was originally developed by (duh) Nullsoft, the folks that brought you Winamp, the most llama-ass-whipping MP3 player ever to grace the early 2000s. It’s long since been spun off into its own thing, which is probably good because I’m not sure there’s much of a market for Winamp these days.
More than a few large pieces of software use NSIS for creating their own installers. It can unzip files, show dialog boxes, and so on. It has its own scripting language, and we’ll use a very little bit of it here.
- Download NSIS from their Sourceforge page, run the installer, click Next a few times. NSIS uses itself in its own installer. How meta.
- Take the files you need to extract, and put them all in the same directory. Just like if you were creating a zip file. Because we sorta are.
- In that same directory, with your text editor of choice (I’m partial to Notepad++), create a file named something.nsi (the latter being the default extension for NSIS scripts). You don’t actually have to name it with that extension, but if you do, most modern editors will do some syntax highlighting for you.
In that file, put something like this:
Name "My Quiet Installer"
OutFile MyInstaller.exe
RequestExecutionLevel admin
SilentInstall silent
Section
InitPluginsDir
SetOutPath "$PLUGINSDIR"
File "YourInstaller.msi"
File "License.key"
ExecWait '"msiexec" /i "$PLUGINSDIR/YourInstaller.msi"'
SectionEnd
Save that file, and drag it into NSIS. A few seconds later, you should have an installer that contains their installer.
Let’s break down the above just a bit.
“OutFile” just specifies the name of NSIS’ output. You can rename it later, no sweat.
“Section” doesn’t have to have a name (it’s not “Section Main” or “Section DoStuff”). That’s something you’d use if you were working on something bigger and more complex than this.
“InitPluginsDir” is a bit odd. We’re not using any plugins. But it creates a uniquely-named temporary directory, that the installer automatically cleans up when you’re done. Saves you a few lines of creating a temporary directory, then explicitly deleting it yourself later.
The two “File” lines specify the files you’re putting into the installer, that will later be “unzipped”. Repeat as needed.
“ExecWait” is one of three options for running other processes. In this case, though, we want the one that waits – the other options will continue running the installer scripts immediately, and deleting the files you just worked so hard to extract.
So, that’s it. When you run the installer you created above, it will silently unzip the contents into a temporary directory, run the specified file from that directory, then delete itself when it’s done. You don’t have to worry about the end-user not knowing how to extract files, because we do it. And you don’t have to worry too much about license key proliferation, because the file deletes itself when it’s done. (True, a malicious user could just sniff around the temp directories and find the license file in the middle of the child install process, but that’s an acceptable risk for me.)