Using NSIS To Make Installable Java Applications

By Rizwan Sattar


Overview

This page is designed to teach you, the programmer, how to make your programs be distributable by making those neat "setup" programs which install your application onto a Windows computer. You will learn how to create a basic script which will be able to copy files to a folder and set up start menu shortcuts, etc. Also, you will learn how to make your programs uninstallable.

What is NSIS (Nullsoft Scriptable Install System A.K.A. Nullsoft Super-Pimp Installation System) ?

If you have installed WinAmp, then you have used an NSIS program to install your software. Why? Because the same people that make WinAMP, Nullsoft Inc., are the ones that have made this great tool for packaging and making your program accessible. Their reason for developing it was mainly to make WinAMP easily distributable, but they then decided to release their installation software to everyone for free. NSIS, as their owners call it, is "the scriptable win32 installer/uninstaller system that doesn't suck and isn't huge."

How does NSIS work?

Once your program is ready to be "deployed" to the world, you need a way to let other people install/uninstall your software. You might not even be a programmer, but need some way of easily letting someone have some files. NSIS packs & compresses all your files into a creates a single .exe file for installing your software. So, the final product is one "setup.exe" file which is easily downloadable and runnable by others. To make a setup executable, you have to write a script of what needs to happen. That is, in that script you will write the following:

  • Set the installation directory (e.g. Program Files\My Cool Program\)
  • If you have different "components" that the user can select / deselect for installation, then specify these choices
  • Copy the files over to the installation directory and possibly others
  • Create registry entries if you need to
  • Set up Start Menu shortcuts, and add to "Add/Remove Programs" in the control panel
  • Instruct what files, registry entries, folders to erase when the user wants to uninstall the application

This is easier than you might think it is. A NSIS script has the extension .nsi, and can be written in any text editor. In that way it's like writing HTML for doing webpages: you could write it in Notepad, or you could write it in Macromedia Dreamweaver. Similarly, there are programs available that let you edit the scripts and provide some useful functions

So instead of having to create your own GUI for installing your program and then somehow figuring out how to package everything so that a novice user can download it, you just write in the script what you want to happen, and NSIS will take care of the GUI for you.

Setting up your the NSIS system on your computer

Once you have written the script it has to be read-in by a "compiler" which will read through your instructions and create the single .exe file you wanted. To get the compiler you have to download NSIS from Nullsoft. You can get it here or by going down to the links section. Once you install this, you are able to compile your .nsi files using the program "MakeNSISW." Just open the program, and then drag and .nsi file into the GUI and it will compile the script into your executable, or it will tell if you made any mistakes in the script and offer some debugging. Below is what the MakeNSISW program looks like:

 

A Basic .nsi Script

The scripting language used by NSIS lets you do a lot of things, so your installation can be as complex as setting up WinAMP, or as simple as just copying a couple of files to a directory. The best source for describing all the functions and capabilities of NSIS is in Nullsoft's NSIS User Manual. It lists all of the features available, so if you have any specific requirements for installing your program, be sure to check it out.


; example1.nsi
;
; This script is perhaps one of the simplest NSIs you can make. All of the
; optional settings are left to their default settings. The installer simply
; prompts the user asking them where to install, and drops a copy of "MyProg.exe"
; there.

;--------------------------------

; The name of the installer
Name "Example1"

; The file to write
OutFile "example1.exe"

; The default installation directory
InstallDir $PROGRAMFILES\Example1

; The text to prompt the user to enter a directory
DirText "This will install My Cool Program on your computer. Choose a directory"

;--------------------------------

; The stuff to install
Section "" ;No components page, name is not important

; Set output path to the installation directory.
SetOutPath $INSTDIR

; Put file there
File
MyProg.exe

SectionEnd ; end the section



Just that script alone will create the following two windows:

Let's look at the script more closely:

Installer Attributes

The first few instructions all define installer attributes. They are used to present the installer to the user. Things that are commonly set here are the order of windows to show, and the text that is shown on each window


Name "Example1" This is the name of the Application that you are trying to install. Note that it shows up in the title bar and also above the textbox in left window
   
OutFile "example1.exe" This is the name of the setup program, so you could call this "setup.exe" and the final file created with be named "setup.exe"
   
InstallDir $PROGRAMFILES\Example1 This line creates a default location for the installation. Note that $PROGRAMFILES is a constant value provided by NSIS
   
DirText "This will..directory" This is the text that is shown on the top of the window where the user must select where to install the program

Sections

Every installation script has at least one "section." Since a typical program has different components that can be optionally installed, the code to copy files associate with certain components is included in sections. For example, some programs install themselves and then offer to install other, supplemental software or plug-ins. If you think about the program you installed most recently, chances are it gaves you some options of what you wanted installed. If the user checks a component to be installed, then that components files much be copied. These components are then installed in "sections."

If your program doesn't have any extras or optional components, then all you need is one section. Think of it as your application has only one component and that component is ALWAYS installed. Sections are usually named and their is displayed to the user as the name of the component. Since we have only one section, the name isn't important, as it won't even be displayed.


Section "" Start a section with the name "". The name could be "install," or even "nothing". This name is shown to the user if there are multiple sections which he/she can choose to install
   
SetOutPath $INSTDIR Sets the location where the files are copied. All file copy statements after this line will be copied to this location, until it is changed
   
File MyProg.exe This line copies the file "MyProg.exe" (which will eventually be packaged in with the setup.exe) to the current OUTPATH
   
SectionEnd This defines the end of a section. Think of it like the end brace "}" in a for loop

Typically sections have a start and an end. All lines inbetween are instructions for what to install for that component. In the basic example, all that the installer does is set the output path to be the installation directory, and then copies one file, "MyProg.exe," to that path.

Additional Useful Actions:

The following is just a small description of how to go about doing some more advanced things. Please refer to the NSIS User's Manual for complete information.


To copy multiple files:
  • Set the outpath and have multiple "File XXXXX" lines in the section
   
To have multiple components
  • As an installer attribute, set the text of the window which will show the components to install. Something like:
    SetComponentText "Please choose the options you would like to install"
  • Now, you must create a separate section for each component that can be checked. Then, only those that are checked will have their section's commands "executed"

Making your application uninstallable

We would all love if programmers remembered to uninstall everything that they installed into your system. So, here's your chance to do your part!

To make your application uninstallable, you must create a section and name it "Uninstall." In there, you put commands to delete all the files and directories, and change whatever settings you set when you installed the application onto the computer. Finally, you put the command WriteUninstaller $INSTDIR\Uninstall.exe into the section where you do the actual installation. And that's it!

When compiling your script, NSIS will look for a section called "Uninstall" and if so, will create an .exe file (based on the name you provided in "WriteUninstaller $INSTDIR\_____").

Here is an example of an uninstall section (the parts that are need to make your application uninstallable are colored:


; This script shows how to make your applicaton uninstallable

;--------------------------------

; The name of the installer
Name "UninstallExample1"

; The file to write
OutFile "uninstallable_setup.exe"

; The default installation directory
InstallDir $PROGRAMFILES\UninstallableSetup\

; The text to prompt the user to enter a directory
DirText "This will install My Cool Program on your computer. Choose a directory"

;--------------------------------

; The stuff to install
Section "" ;No components page, name is not important

; Set output path to the installation directory.
SetOutPath $INSTDIR

; Put a file there
File
MyProg.exe

; Tell the compiler to write an uninstaller and to look for a "Uninstall" section
WriteUninstaller $INSTDIR\Uninstall.exe

SectionEnd ; end the section

; The uninstall section
Section "Uninstall"

Delete $INSTDIR\Uninstall.exe
Delete $INSTDIR\MyProg.exe
RMDir $INSTDIR

SectionEnd


Creating Start Menu Items

For those of you who don't know, the start menu / Programs is actually a folder which sits in your computer (inside C:\Windows under 9x/ME, and under "C:\Documents and Settings\Username\Start Menu\Programs" for XP), and as a bunch of links. To create start menu items, you just need to use the functions CreateDirectory and CreateShortCut to add links to the start menu.

The following is a small example on creating shortcuts. Please read the User's Manual and go to the Forums for information on creating different kinds of shortcuts

In a section which is installing files:


; The stuff to install
Section "" ;No components page, name is not important

; Set output path to the installation directory.
SetOutPath $INSTDIR

; Add some files, so installation stuff...
; ...
; ...
; ...
; Now create shortcuts

CreateDirectory "$SMPROGRAMS\Rizwan Inc."
CreateShortCut "$SMPROGRAMS\Rizwan Inc.\Run Rizwan's Program.lnk" "$INSTDIR\Rizwan.exe"
CreateShortCut "$SMPROGRAMS\Rizwan Inc.\Open Notepad.lnk" "Notepad.exe"



SectionEnd ; end the section


The above statements will create a program group in your start menu called "Rizwan Inc." and in there it will create a shortcut called "Run Rizwan's Program", which in turn points to the actual program, in this case called "Rizwan.exe." For sake of example, another shortcut is created called "Open Notepad" which opens the Windows Notepad program. Notice that the term $SMPROGRAMS is built-in to make it very easy for you to install it to the start menu. You don't have to worry about where exactly the start menu is and for which user you are installing it for ($SMPROGRAMS points to the start menu of the current user)

If you have created shortcuts, then you should also remove them when you are uninstalling. This is done in the same way as deleting any other file or folder

For example, under the Uninstall section:


Section "Uninstall"

; Delete the files and folders we created during install
; ...
; ...
; ...
; Now remove shortcuts too

Delete "$SMPROGRAMS\Rizwan Inc.\Run Rizwan's Program.lnk"
Delete "$SMPROGRAMS\Rizwan Inc.\Open Notepad.lnk"

RMDIR "$SMPROGRAMS\Rizwan Inc."

SectionEnd ; end the section


 

NSIS and Java

Let's make an installer for a Java application. Java applications are started with a "java MyApplication" kind of call. That is, it is a call to the Java Virtual Machine (java.exe) to load the .class file "MyApplication.class." For that reason (and some others), java application installers must be differ from regular application installers in the following ways:

  • Naturally, a Java Runtime Environment must be installed. That is, a Java Virtual Machine must exist in the system. This can or cannot be checked for.
  • Sometimes, environment variables must be set for the Java application to work. The classpath becomes an issue. This is dependendent on the java application
  • If a Java .class file can be placed anywhere, how does it find the classes that it uses?
  • Start menu shortcuts to run Java applications must be created more carefully.

Java applications are not much different from regular Windows applications, except for that they are not .exe files, but are .class files which javaw.exe must start. Javaw.exe is the version of java.exe which suppresses the System.out stream, which also removes the need for a DOS prompt which typically shows up every time you run a java program.

Checking for a Java Runtime Environment

If a JRE is installed, the windows\system32 directory will have both java.exe and javaw.exe, so we can check for the existence of those files to tell if a JRE exists. The NSIS Archive actually has a example of how to check the JDK version, so that is worth taking a look at. If the system doesn't have a JRE installed, then it won't be able to launch java applications. You could either notify the user and direct him/her where to download a JRE, or provide one from within our installation package.

The JRE from Sun Microsystems is freely available to download and can be freely distributed as well, so that is another strategy for ensuring that java is installed. We could just download the JRE installer from Sun Microsystems, and then provide that as part of the installation. How do you run a program from the installer? If you use the Exec command from NSIS, we can "execute" the JRE installer that we packaged as part of our installer. However, Exec runs the command and continues immediately; it is a non-blocking call. What we would like is for the JRE to install and then continue on with the rest of the installation. For that reason, use ExecWait. Just make sure that the JRE installer is first extracted with the File command to either a temp directory or the install directory first and then execute that.

Environment Variables

To set environment variables, the NSIS Archive has a great example / tutorial on how to set environment variables.

How does a java application find all the classes that it uses? (Setting the working directory)

In almost all operating systems, a call can be made to an executable file from anywhere. Suppose you have MyApplication.exe placed in C:\TestExe\. To run MyApplication.exe, you typically would go to the TestExe directory and then call:

C:\TextExe\> MyApplication

However, we could be in a folder like C:\Another_Folder\Inside_yet_another_folder\ and still be able to execute MyApplication.exe. How? Like this:

C:\Another_Folder\Inside_yet_another_folder\> C:\TestExe\MyApplication

This kind of example works in Unix as well (of course, the directories wouldn't be starting with "C:". What is different about these two program calls. The working directory of each application is different. In the first example, the working directory is C:\TestExe because that is where we launched the application from. In the second example the working directory is C:\Another_Folder\Inside_yet_another_folder . The working directory is the directory from which the application is launched. As you have seen, it doesn't necessarily have to be the directory where the program is installed.

Go to your start menu, and under programs, find a shortcut. Right-click on this shortcut and now in the new window, look at the text box labelled "Start In:". That is the working directory of that application.

How do we make sure that the working directory in our shortcuts are where we want them to be? There is no parameter to set for that in the CreateShortcut function in NSIS. Look back to the first example where we created start menu shortcuts. Notice that we have set an Outpath for copying files. This Outpath is ALSO set as the working directory for every shortcut that is created after that SetOutPath command. If you would like to change the working directory of a shortcut, then simply change the OutPath to what you would like, create the shortcut, and then, if you want, change the OutPath back.

Creating Start Menu shortcuts for running java .classes

Typically, the target of a shortcut in the start menu is a simple .exe file or a .bat file of some sort. If you look at any shortcut's properties in your start menu, you may notice that the "Target" field is in quotations. For simple targets, Windows likes to put quotes around the entire call.

What happens when you have a target that takes in some kind of command line parameter? For example, you have a .exe file but it takes a number after it. The call to the function would have to be something like:

C:\Path_of_exe_file\MyApplication.exe 5

When you have some target such as this, Windows doesn't like to put quotes around the program call. Why does this matter to a java application? Since to run a java program, one has to type "javaw MyApplication," it can be seen as a call to an .exe file ("javaw.exe") which takes in a parameter (the class name, or "MyApplication). Thus, we cannot have quotes around the target in our shortcut. The following then, will not work:

CreateShortCut "$SMPROGRAMS\Rizwan Inc.\Run Rizwan's Java Program.lnk" "$SYSDIR\javaw.exe MyApplication"

What we need to do is create a shortcut for executing 'javaw.exe' but pass the classname, jar file, or other stuff as a parameter. This is done by simply adding another "quotation" part after the executable part, like this:

CreateShortCut "$DESKTOP\Run My Java Program.lnk" "$SYSDIR\javaw.exe" "MyJavaClass"

To run a java class from a jar file, you can type something like this:

CreateShortCut "$DESKTOP\Run My Java Program.lnk" "$SYSDIR\javaw.exe" "-jar MyGreatJarFile.jar"

The extra "quotation" section with our classname is all you need to run your java application. If you like, you can attach an icon to your java application, by adding ANOTHER quotation section like so:

CreateShortCut "$DESKTOP\Run My Java Program.lnk" "$SYSDIR\javaw.exe" "MyJavaClass" "$INSTDIR\MyIcon.ico"

Of course, you'll need your icon file to be installed to your installed directory, so don't forget to do that.

A Java Example

Here is the .nsi script for a program which installs a Java application which uses one .class file, NSISExampleApplication1.class. More specifically, it does the following:

  • Copies both the .class file and .java file to the installed directory
  • Copies a readme.txt
  • Copies itself (the script) to the installed directory
  • Creates start menu icons for running the example application
  • Creates registry keys for uninstallability from Add/Remove programs in the Windows control panel
  • Makes the application uninstallable

Look at the script below for doing the above tasks. It may look a little intimidating, but there is a lot of whitespace and comments to make it easier to understand:


; Name of our application
Name "NSIS Example Application 1"

; The file to write
OutFile "Setup_NSISExampleApp1.exe"

; Set the default Installation Directory
InstallDir "$PROGRAMFILES\NSIS Example Application 1"

; Set the text which prompts the user to enter the installation directory
DirText "Please choose a directory to which you'd like to install this application."

; ----------------------------------------------------------------------------------
; *************************** SECTION FOR INSTALLING *******************************
; ----------------------------------------------------------------------------------


Section "" ; A "useful" name is not needed as we are not installing separate components

; Set output path to the installation directory. Also sets the working
; directory for shortcuts

SetOutPath $INSTDIR\

File NSISExampleApplication1.class
File NSISExampleApplication1.java
File readme.txt
File createInstaller1.nsi

WriteUninstaller $INSTDIR\Uninstall.exe

; ///////////////// CREATE SHORT CUTS //////////////////////////////////////

CreateDirectory "$SMPROGRAMS\NSIS Example Application 1"


CreateShortCut "$SMPROGRAMS\NSIS Example Application 1\Run NSIS Example Application 1.lnk" "$SYSDIR\javaw.exe" "NSISExampleApplication1"


CreateShortCut "$SMPROGRAMS\NSIS Example Application 1\Uninstall Example Application 1.lnk" "$INSTDIR\Uninstall.exe"

; ///////////////// END CREATING SHORTCUTS //////////////////////////////////

; //////// CREATE REGISTRY KEYS FOR ADD/REMOVE PROGRAMS IN CONTROL PANEL /////////

WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Example Application 1" "DisplayName"\
"NSIS Example Application 1 (remove only)"

WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Example Application 1" "UninstallString" \
"$INSTDIR\Uninstall.exe"

; //////////////////////// END CREATING REGISTRY KEYS ////////////////////////////

MessageBox MB_OK "Installation was successful."

SectionEnd

; ----------------------------------------------------------------------------------
; ************************** SECTION FOR UNINSTALLING ******************************
; ----------------------------------------------------------------------------------

Section "Uninstall"
; remove all the files and folders
Delete $INSTDIR\Uninstall.exe ; delete self
Delete $INSTDIR\NSISExampleApplication1.class
Delete $INSTDIR\NSISExampleApplication1.java
Delete $INSTDIR\readme.txt
Delete $INSTDIR\createInstaller1.nsi

RMDir $INSTDIR

; now remove all the startmenu links
Delete "$SMPROGRAMS\NSIS Example Application 1\Run NSIS Example Application 1.lnk"
Delete "$SMPROGRAMS\NSIS Example Application 1\Uninstall Example Application 1.lnk"
RMDIR "$SMPROGRAMS\NSIS Example Application 1"

; Now delete registry keys
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\NSIS Example Application 1"
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Example Application 1"

SectionEnd


If you have NSIS installed, then compile the script and files and see what happens. Download and extract: NSISExampleApplication.zip (4K)

If you would like to just get the installer .exe, download: Setup_NSISExampleApp1.exe (39K)

Resources

This is by no means a complete guide to creating an installer. Please look at the following links for more information.

  • NSIS Main Website - Where you can go to download NSIS and look for future versions
  • NSIS User's Manual - A very comprehensive guide to how to use NSIS, plus a reference section which is very useful
  • NSIS Discussion Forums - Searching for previous posts on this forum can help you to find the answer to a question
  • NSIS Archives - A very good collection of sample scripts, plus a wide array of NSIS script editors
  • NSIS Workbench - A very good NSIS script editor, if you want something that helps you write the scripts