NSIS (Nullsoft Scriptable Install System, http://nsis.sourceforge.net/) is a tool that allows programmers to create installers for Windows. This library provides an alternative syntax for NSIS scripts, as an embedded Haskell language, removing much of the hard work in developing an install script. Simple NSIS installers should look mostly the same, complex ones should be significantly more maintainable.
As a simple example of using this library:
import Development.NSIS main = writeFile "example1.nsi" $
name"Example1" -- The name of the installer
outFile"example1.exe" -- Where to produce the installer
installDir"$DESKTOP/Example1" -- The default installation directory
User-- Request application privileges for Windows Vista -- Pages to display
Directory-- Pick where to install
InstFiles-- Give a progress bar while installing -- Groups fo files to install
section""  $ do
setOutPath"$INSTDIR" -- Where to install files in this section
file "Example1.hs" -- File to put into this section
example1.nsi can now be processed with
makensis to produce the installer
For more examples, see the
Examples source directory.
Much of the documentation from the Installer section is taken from the NSIS documentation.
- nsis :: Action () -> String
- nsisNoOptimise :: Action () -> String
- data Action a
- type Exp ty = Action (Value ty)
- data Value ty
- share :: Exp t -> (Exp t -> Action a) -> Action a
- scope :: Action a -> Action a
- constant :: Typeable t => String -> Exp t -> Action (Exp t)
- constant_ :: Exp t -> Action (Exp t)
- mutable :: Typeable t => String -> Exp t -> Action (Exp t)
- mutable_ :: Exp t -> Action (Exp t)
- (@=) :: Exp t -> Exp t -> Action ()
- mutableInt, constantInt :: String -> Exp Int -> Action (Exp Int)
- mutableInt_, constantInt_ :: Exp Int -> Action (Exp Int)
- mutableStr, constantStr :: String -> Exp String -> Action (Exp String)
- mutableStr_, constantStr_ :: Exp String -> Action (Exp String)
- iff :: Exp Bool -> Action () -> Action () -> Action ()
- iff_ :: Exp Bool -> Action () -> Action ()
- while :: Exp Bool -> Action () -> Action ()
- loop :: (Action () -> Action ()) -> Action ()
- onError :: Action () -> Action () -> Action ()
- (?) :: Exp Bool -> (Exp t, Exp t) -> Exp t
- (%&&), (%||) :: Exp Bool -> Exp Bool -> Exp Bool
- data Label
- newLabel :: Action Label
- label :: Label -> Action ()
- goto :: Label -> Action ()
- (%==), (%/=) :: Exp a -> Exp a -> Exp Bool
- (%<=), (%>), (%>=), (%<) :: Exp Int -> Exp Int -> Exp Bool
- true, false :: Exp Bool
- not_ :: Exp Bool -> Exp Bool
- strRead :: Exp String -> Exp Int
- strShow :: Exp Int -> Exp String
- (&) :: Exp String -> Exp String -> Exp String
- strConcat :: [Exp String] -> Exp String
- strLength :: Exp String -> Exp Int
- strTake :: Exp Int -> Exp String -> Exp String
- strDrop :: Exp Int -> Exp String -> Exp String
- strReplace :: Exp String -> Exp String -> Exp String -> Exp String
- strIsPrefixOf :: Exp String -> Exp String -> Exp Bool
- strUnlines :: [Exp String] -> Exp String
- data FileHandle
- fileOpen :: FileMode -> Exp FilePath -> Action (Exp FileHandle)
- fileWrite :: Exp FileHandle -> Exp String -> Action ()
- fileClose :: Exp FileHandle -> Action ()
- withFile' :: FileMode -> Exp FilePath -> (Exp FileHandle -> Action ()) -> Action ()
- writeFile' :: Exp FilePath -> Exp String -> Action ()
- writeFileLines :: Exp FilePath -> [Exp String] -> Action ()
- rmdir :: [Attrib] -> Exp FilePath -> Action ()
- delete :: [Attrib] -> Exp FilePath -> Action ()
- getFileTime :: Exp FilePath -> Exp String
- fileExists :: Exp FilePath -> Exp Bool
- findEach :: Exp FilePath -> (Exp FilePath -> Action ()) -> Action ()
- createDirectory :: Exp FilePath -> Action ()
- createShortcut :: Exp FilePath -> [Attrib] -> Action ()
- readRegStr :: HKEY -> Exp String -> Exp String -> Exp String
- deleteRegKey :: HKEY -> Exp String -> Action ()
- writeRegStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
- writeRegDWORD :: HKEY -> Exp String -> Exp String -> Exp Int -> Action ()
- exec :: Exp String -> Action ()
- name :: Exp String -> Action ()
- outFile :: Exp FilePath -> Action ()
- installDir :: Exp FilePath -> Action ()
- setCompressor :: Compressor -> [Attrib] -> Action ()
- installIcon, uninstallIcon :: Exp FilePath -> Action ()
- headerImage :: Maybe (Exp FilePath) -> Action ()
- installDirRegKey :: HKEY -> Exp String -> Exp String -> Action ()
- allowRootDirInstall :: Bool -> Action ()
- caption :: Exp String -> Action ()
- showInstDetails :: Visibility -> Action ()
- showUninstDetails :: Visibility -> Action ()
- data SectionId
- section :: Exp String -> [Attrib] -> Action () -> Action ()
- sectionGroup :: Exp String -> [Attrib] -> Action () -> Action ()
- newSectionId :: Action SectionId
- sectionSetText :: SectionId -> Exp String -> Action ()
- sectionGetText :: SectionId -> Exp String
- uninstall :: Action () -> Action ()
- page :: Page -> Action ()
- unpage :: Page -> Action ()
- file :: [Attrib] -> Exp FilePath -> Action ()
- alwaysNonFatal :: Action () -> Action ()
- writeUninstaller :: Exp FilePath -> Action ()
- alert :: Exp String -> Action ()
- setOutPath :: Exp FilePath -> Action ()
- messageBox :: [MessageBoxType] -> Exp String -> Action (Exp String)
- requestExecutionLevel :: Level -> Action ()
- hideProgress :: Action a -> Action a
- detailPrint :: Exp String -> Action ()
- data Compressor
- data HKEY
- data MessageBoxType
- data Attrib
- data Page
- data Level
- data Visibility
- data FileMode
Create the contents of an NSIS script from an installer specification.
nsis, but don't try and optimise the resulting NSIS script. Useful
to figure out how the underlying installer works, or if you believe the
optimisations are introducing bugs (but please do report any such bugs!).
Monad in which installers are defined. A useful command to start with is
fromString function converts any embedded
$VAR into a variable lookup, which may refer to one of
the builtin NSIS variables (e.g.
$PROGRAMFILES), or a named variable
mutable. The string
$$ is used to escape
Bracket the variables to put text characters afterwards (e.g.
$(SMPROGRAMS)XXX). In contrast
to standard strings,
/ is treated as
// is treated as
/. Remember to escape any
slashes occuring in URLs.
Ord instances for
Exp throw errors for all comparisons (use
max are defined. The
Num (arithmetic) and
Monoid (string concatenation) instances are both
fully implemented. From
div are implemented, and
all as integer arithmetic. No functions from
Real are implemented.
When using a single expression multiple times, to ensure it is not evaluated
Exp language is call-by-name, meaning you must use share to avoid evaluating an exression
multiple times. Using
share, if the expression has any side effects
they will be run immediately, but not on subsequent uses. When defining functions operating on
Exp, if you use the same input expression twice, you should share it. For example:
If the expression was not shared, and
x read from a file, then the file would be read twice.
Introduce a variable scope. Scopes are automatically introduced by operations
while etc. Inside a scope you may define new variables
whose names may clash with variables outside the scope, but the local versions will be used.
It is important to turn
x into a
constant_ before defining a new constant
x refers to
$TEST after the new definition, it will pick up the wrong variable.
A code label, used for
goto programming, see
Create a new label, used with
label to write line jump based programming.
Where possible you should use structured alternatives, such as
Each created label must be used with one call to
label, and any number of calls to
goto. As an example:
whilevar $ do
Note that the above example could have been written in a simpler manner with
The standard comparison operators, lifted to
Concatenate two strings, for example
"$FOO" & "$BAR" is equivalent
Take the first
n characters from a string,
strTake 2 "test" .
Drop the first
n characters from a string,
strDrop 2 "test" .
Replace one string with another string, in a target string. As some examples:
strReplace "t" "XX" "test" %== "XXesXX" strReplace "ell" "" "hello world" %== "ho world"
Is the first string a prefix of the second.
Join together a list of strings with
\r\n after each line. Note that unlike standard
we use the Windows convention line separator.
File system manipulation
Write a string to a file openned with
Write a file comprising of a set of lines.
Remove the specified directory (fully qualified path with no wildcards). Without
the directory will only be removed if it is completely empty. If
Recursive is specified, the
directory will be removed recursively, so all directories and files in the specified directory
will be removed. If
RebootOK is specified, any file or directory which could not have been
removed during the process will be removed on reboot -- if any file or directory will be
removed on a reboot, the reboot flag will be set.
The error flag is set if any file or directory cannot be removed.
rmdir  "$INSTDIR" rmdir  "$INSTDIR/data" rmdir [Recursive, RebootOK] "$INSTDIR" rmdir [RebootOK] "$INSTDIR/DLLs"
Note that the current working directory can not be deleted. The current working directory is
setOutPath. For example, the following example will not delete the directory.
setOutPath "$TEMP/dir" rmdir  "$TEMP/dir"
The next example will succeed in deleting the directory.
setOutPath "$TEMP/dir" setOutPath "$TEMP" rmdir  "$TEMP/dir"
rmdir [Recursive] $INSTDIR in
uninstall is not safe. Though it is unlikely,
the user might select to install to the Program Files folder and so this command will wipe out
the entire Program Files folder, including other programs that has nothing to do with the uninstaller.
The user can also put other files but the program's files and would expect them to get deleted with
the program. Solutions are available for easily uninstalling only files which were installed by the installer.
Delete file (which can be a file or wildcard, but should be specified with a full path) from the target system.
RebootOK is specified and the file cannot be deleted then the file is deleted when the system reboots --
if the file will be deleted on a reboot, the reboot flag will be set. The error flag is set if files are found
and cannot be deleted. The error flag is not set from trying to delete a file that does not exist.
delete  "$INSTDIR/somefile.dat"
Gets the last write time of the file, you should only use the result to compare for equality
with other results from
getFileTime. On failure the error flag is set.
Checks for existence of file(s) (which can be a wildcard, or a directory).
If you want to check to see if a file is a directory, use
iff_ (fileExists "$WINDIR/notepad.exe") $ messageBox [MB_OK] "notepad is installed"
Performs a search for filespec, running the action with each file found. If no files are found the error flag is set. Note that the filename output is without path.
findEach "$INSTDIR/*.txt" $ \x -> detailPrint x
If you jump from inside the loop to after the loop then you may leak a search handle.
Creates (recursively if necessary) the specified directory. Errors can be caught
onError. You should always specify an absolute path.
Creates a shortcut file that links to a
Traget file, with optional
Parameters. The icon used for the shortcut
StartOptions should be one of: SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED.
KeyboardShortcut should be in the form of 'flag|c' where flag can be a combination (using |) of: ALT, CONTROL, EXT, or SHIFT.
c is the character to use (a-z, A-Z, 0-9, F1-F24, etc). Note that no spaces are allowed in this string. A good example is
$OUTDIR is used for the working directory. You can change it by using
setOutPath before creating
Description should be the description of the shortcut, or comment as it is called under XP.
The error flag is set if the shortcut cannot be created (i.e. either of the paths (link or target) does not exist, or some other error).
createDirectory "$SMPROGRAMS/My Company" createShortcut "$SMPROGRAMS/My Company/My Program.lnk" [Target "$INSTDIR/My Program.exe" ,Parameter "some command line parameters" ,IconFile "$INSTDIR/My Program.exe", IconIndex 2 ,StartOptions "SW_SHOWNORMAL" ,KeyboardShortcut "ALT|CONTROL|SHIFT|F5" ,Description "a description"]
Execute the specified program and continue immediately. Note that the file specified
must exist on the target system, not the compiling system.
$OUTDIR is used for the working
directory. Errors can be caught using
onError. Note, if the command could have spaces,
you should put it in quotes to delimit it from parameters. e.g.:
exec "\"$INSTDIR/command.exe\" parameters".
If you don't put it in quotes it will not work on Windows 9x with or without parameters.
exec "\"$INSTDIR/someprogram.exe\"" exec "\"$INSTDIR/someprogram.exe\" some parameters"
Global installer options
Sets the name of the installer. The name is usually simply the product name such as 'MyApp' or 'Company MyApp'.
Specifies the output file that
MakeNSIS should write the installer to.
This is just the file that MakeNSIS writes, it doesn't affect the contents of the installer.
Usually should end with
Sets the default installation directory.
Note that the part of this string following the last
\ will be used if the user selects
may be appended back on to the string at install time (to disable this, end the directory with a
If this doesn't make any sense, play around with the browse button a bit.
Set the icon used for the installer/uninstaller.
Set the image used for the header splash. Pass
Nothing to use the default header image.
headerImage $ Just "$NSISDIR/Contrib/Graphics/Header/win.bmp"
This attribute tells the installer to check a string in the registry,
and use it for the install dir if that string is valid. If this attribute is present,
it will override the
installDir attribute if the registry key is valid, otherwise
it will fall back to the
installDir default. When querying the registry, this command
will automatically remove any quotes. If the string ends in ".exe", it will automatically
remove the filename component of the string (i.e. if the string is "C:program filesfoo/foo.exe",
it will know to use "C:program filesfoo").
installDirRegKey HKLM "Software/NSIS" "" installDirRegKey HKLM "Software/ACME/Thingy" "InstallLocation"
Writes the uninstaller to the filename (and optionally path) specified.
Only valid from within an install section, and requires that you have an
uninstall section in your script.
You can call this one or more times to write out one or more copies of the uninstaller.
Sets the output path (
$OUTDIR) and creates it (recursively if necessary), if it does not exist.
Must be a full pathname, usually is just
While the action is executing, do not update the progress bar. Useful for functions which do a large amount of computation, or have loops.
Display with an OK button
Display with an OK and a cancel button
Display with abort, retry, ignore buttons
Display with retry and cancel buttons
Display with yes and no buttons
Display with yes, no, cancel buttons
Display with exclamation icon
Display with information icon
Display with question mark icon
Display with stop icon
Display with installer's icon
Make messagebox topmost
Right align text
RTL reading order
Button 1 is default
Button 2 is default
Button 3 is default
Button 4 is default
|Description (Exp String)|
|Target (Exp String)|
|Parameters (Exp String)|
|IconFile (Exp String)|
|IconIndex (Exp Int)|