Deploy your code in a single installer alongside its LabJack dependencies.
We've done the hard parts, so to get started you'll add your files to a LabJack-based NSIS installer. From there, you can re-brand and prepare your installer for distribution.
- Get up and running quickly by following LabJack's example
- Distribute one installer: make it simple for your users
- Customize and re-brand your installer
- Receive modular updates from LabJack at your own pace
- Create a custom install so you can rely on specific LabJack file versions
- Minimal install: get rid of the files you don't need
If you have LabJack dependencies and you already have an installer already (or if you don't want to use NSIS), you have other options:
Call The LabJack Basic Installer
Call the LabJack Basic Installer silently from your own installer.
This is convenient, but the public LabJack installer file versions may conflict with the LabJack file versions your code relies on. If your code does depend on very specific LabJack file versions, read on.
Manually Install LabJack Files
Manually installing LabJack files allows you to put LabJack files wherever you need them to keep them from conflicting with the public LabJack installer file versions. You can use the .nsi scripts in installer_src/labjack/
to figure out what LabJack files are needed.
- A code signing certificate - note that this can take a week or so to be approved.
- LabJack files, which can be downloaded from https://s3.amazonaws.com/lj-amalg-win/latest/Files.zip
- A working knowledge of NSIS. (Don't worry - you can follow LabJack's example and the NSIS documentation is concise.)
The unmodified lj_amalg.nsi does a couple of things. Briefly:
- Declares necessary installer variables / macros
- Uses NSIS Modern User Interface
- Installs "LabJack Installer Sections"
- These sections install files and write Windows registry values
- Provides placeholder installation and uninstallation sections in
installer_src\custom\my_section.nsi
for your files - Sets up "LabJack Uninstaller Sections"
- These do the opposite of their corresponding installer sections
- Upon installer initialization, checks for an existing installation (see
Function .onInit
)- If an appropriate uninstaller is in the Windows registry, runs the uninstaller
- If files continue to exist after the uninstaller runs, prompts the user to manually remove the files and aborts installation. (Future versions may automatically fix this.)
Let's start with re-branding your installer. This changes the installer name, icon, website, etc. More importantly, it sets the InstallDir
path to install to a custom location.
To re-brand your installer as your own, search lj_amalg.nsi for the string changeme
. Among the things you'll need to change:
- The
Name
command - Change the Icon:
- Change the
Icon
path - Change the
UninstallIcon
path
- Change the
- Change the file name passed to the
OutFile
command !define COMPANY
!define URL
First, put your files to be installed into the Files
directory.
Next, edit installer_src\custom\my_section.nsi
to tell NSIS where files are on your machine (where you just put them) and where you want files to be installed.
The path for each File
command must be given relative to .nsi script that uses !include
to include my_section.nsi
- the directory containing this readme.md
and lj_amalg.nsi
. Also, make sure you set the path using the SetOutPath
command.
Edit the section in installer_src\custom\my_section.nsi
named -un.my_section
. You only need to remove the custom files you install.
!include
pulls in a .nsi
file as if it was written directly in the including file itself. This means:
- the order of the sections is set by the
!include
order - the file paths passed to the
File
command should be relative to the including file (or absolute)
LabJack sections are !include
d in a modular format. There are two levels (driver and app) and two stacks: LJM and UD. (LJM is for T-series devices and Digits; UD is for U3 / U6 / and UE9.) LJM and UD both share some files dependencies, so if you need either a LJM or UD section, then you should leave the shared
section, as well. Note that if you remove a driver section for a given stack, apps for that stack will not be able to run; e.g. if you remove the driver_ud.nsi
, then app_ud.nsi
should be removed as well.
Also note that each LabJack install section has a corresponding uninstall section that begins with un_
. For example, driver_ud.nsi
's uninstall section is un_driver_ud.nsi
.
The driver_ljm.nsi
section uses the NSIS AccessControl Plugin, which is included in nsis_plugins
via !addplugindir
.
You can remove unneeded LabJack sections to reduce your installer size.
To remove LabJack sections, edit lj_amalg.nsi
to remove the !include
statements that include unwanted LabJack sections. For example, if your users won't need to use LabJack graphical applications, remove the !include
statements that include app
.nsi scripts. Don't forget to remove the uninstall sections, as well!
Once you're ready to prepare your installer for distribution you'll need to compile, sign, and test your installer.
It's not hard. Read on!
For example:
makensis.exe /P2 lj_amalg.nsi
To sign your installer, you'll need to get a SHA256 code signing certificate from a trusted Certificate Authority (CA). Wikipedia has a pretty good introduction if you'd like to know more about code signing. Note that it may take a while for a CA to issue you a certificate, so get the process started before you need it. Also, note that if you'll need a SHA1 certificate for dual-signing in order to support Windows XP and Vista.
Once you have your SHA256 code signing certificate, you'll need to convert it into a .pfx file. There are a few different formats your CA may distribute the certificate to you, so follow the instructions below that match. Note that if you want to dual-sign, you'll need a .pfx for both your SHA1 and your SHA256 certificates.
___.pem and .key to .pfx___
openssl pkcs12 -inkey my_key.key -in my_cert.pem -export -out my_cert.pfx
___.key (or .pvk) and .spc to .pfx___
Convert the .key to .pvk:
pvk.exe -in my_key.key -strong -topvk -out my_key.pvk
Then, export .spc and .pvk to .pfx:
pvkimprt -PFX my_cert.spc my_key.pvk
In the wizard that pops up:
- You should export your private key (you're exporting it to the .pfx file you're creating)
- The "Export File Format" should be "Personal Information Exchange - PKCS #12 (.PFX)" and:
- You should include all certificates in the certification path
- You should export all extended properties
If you get stuck, GoDaddy has a good article on code signing and .pfx creation.
With your .pfx, sign your installer. For dual-signing, you'll sign your installer with both a SHA256 and a SHA1 certificate. For example, you can use SignTool to dual-sign:
signtool.exe sign ^
/t http://tsa.starfieldtech.com/ ^
/d "Awesome Installer" ^
/du https://example.com ^
/p mypassword ^
/f my_sha1.pfx ^
/v AwesomeInstaller.exe
signtool.exe sign ^
/fd sha256 ^
/tr http://tsa.starfieldtech.com/ ^
/td sha256 ^
/as ^
/d "Awesome Installer" ^
/du https://example.com ^
/p mypassword ^
/f my_sha2.pfx ^
/v AwesomeInstaller.exe
If you don't need to dual-sign, just use SignTool as above to sign with your SHA256 .pfx, but without the /as
option.
Following signing, you'll want to verify the signature. For example, to verify a dual-signed .exe:
signtool.exe verify /ds 0 /hash SHA1 /pa AwesomeInstaller.exe
signtool.exe verify /ds 1 /hash SHA256 /pa AwesomeInstaller.exe
Finally, you'll need to test your installer. You'll want to:
- Make sure files install correctly on all the versions of Windows that you support (XP in particular has some complexities)
- Make sure files uninstall correctly
- Beware of
Delete /REBOOTOK
causing problems: When you run the installer, then run the installer again, then reboot, make sure all files are as they should be. Also, you can check the uninstaller log output for "Delete on reboot" (you can right click on the log and copy all the log output).
Now you're an NSIS wizard - there's no twist! Now you can distribute your installer to happy users. All that's left is updating your installer.
When updating, you need to update the files to be installed and the installer itself.
Currently, LabJack distributes this as a binary .zip file. Download it from here:
https://s3.amazonaws.com/lj-amalg-win/latest/Files.zip
Or, install a version of LabJack's file's using the public LabJack installer, then copy the specific files from where they are installed into this directory's File\
directory.
Custom LabJack File Versions
Are you dependent on particular versions of LabJack files? In this case, if a user runs the public LabJack installer (for example, if they need particular versions of LabJack files) it may break your application.
To solve this, you should install custom LabJack file versions:
- You need to change the names of the LabJack files in your installer that are installed to
$SYSDIR
. For example, add a prefix - e.g.LabJackM.dll
becomesmyapp_LabJackM.dll
. - You need to make sure your deployed code (if any) uses the LabJack files in your
$INSTDIR
directory rather than LabJack's$INSTDIR
directory (LabJack's LJM documentation shows the probable$INSTDIR
locations for LJM files on Windows, which is the same for UD files). - If using LJM: the default LJM constants file (
$APPDATA\LabJack\LJM\ljm_constants.json
) is hardcoded in LJM:- You need to edit
driver_ljm.nsi
to change the install location to a custom location instead of$APPDATA\LabJack
- You need to use the
LJM_WriteLibraryConfigStringS
function during your application's initialization to set theLJM_CONSTANTS_FILE
parameter to your custom location
- You need to edit
For whatever files you add a custom prefix to, make sure you find all instances of the file name in all files.
Receive modular updates from LabJack by cloning this repository. Then, pull in updates when you're ready.
If you don't have lots of changes, it should be easy to merge your working branch with LabJack's origin master branch.
If you have lots of changes, you may simply want use the git history of LabJack's origin master branch to manually update your installer as needed. (Also, give us Feedback if it gets frustrating or if you have a better way.)
- The uninstaller does not delete itself when run as part of the installer (from within
Function .onInit
). This is generally not a problem because the installer will be executed immediately after (unless the user aborts installation).
If you're using this, please let us know how it's working for you. We will try to make it better for you (if you let us know how) because we want you to succeed!