Whilst packaging up a plugin based on the Skype API that I had been writing, I was looking for a way to bundle it all up cleanly. The finished plugin consisted of an .exe, a COM wrapper DLL (the very useful Skype4COM wrapper), and some HTML documentation for the C++ code (generated by doxygen). I thought this might be a good opportunity to have a look at NSIS, the installer generator that is used by a huge number of open-source (and other) projects.
My install requirements were quite simple. The following steps needed to be performed:
- Copy the .exe and associated HTML docs to the target system;
- Copy the COM DLL to the target system;
- Register the COM server (by invoking
regsvr32
); - Create any necessary Start Menu items (and an uninstaller);
- Open a web browser automatically on the index page documentation.
Obviously, the uninstaller would need to remove all files, and also unregister the COM server before uninstalling.
I downloaded NSIS from the web site and fired up the NSIS Compiler. This is a very simple interface that allows you to drag-and-drop .NSI script files into its interface and execute them. The NSIS scripting runtime is a very simple scripting language, with some basic language constructs, and the ability to define and import macros and plugins for extended functionality.
A screenshot of the compiler interface is shown below:
Here is the full installation script for my plugin, annotated with some comments.
; Skype Plugin NSIS Installer Script File ; Rory Winston <rory@researchkitchen.co.uk> ;-------------------------------- ;Include some predefined NSIS libraries (for modern UI look and feel) !include "MUI.nsh" ;-------------------------------- XPStyle on ;General ;Name and file Name "Skype Plugin" OutFile "SkypePluginInstaller.exe" ;Default installation folder InstallDir "$PROGRAMFILES\Skype Plugin" ;Get installation folder from registry if available InstallDirRegKey HKCU "Software\Skype Plugin" "" ;-------------------------------- ;Interface Settings !define MUI_ABORTWARNING ;-------------------------------- ;Pages ; These are predefined "wizard pages" that NSIS can generate for us. Note that I ; am including a custom license file on the MUI_PAGE_LICENSE page. !insertmacro MUI_PAGE_LICENSE "NOTICE.txt" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ; Show a custom splash screen on installer entry Function .onInit InitPluginsDir File /oname=$PLUGINSDIR\splash.bmp "installer.bmp" splash::show 1000 $PLUGINSDIR\splash Pop $0 ; $0 has '1' if the user closed the splash screen early, ; '0' if everything closed normally, and '-1' if some error occurred. FunctionEnd ;-------------------------------- ;Installer Sections Section "Install Skype Plugin" SecSkypePlugin SetOutPath "$INSTDIR" ; Copy all of the required files (note the /r switch to recursively copy directories) File "SkypePlugin.exe" File "Tariffs.dat" File /r "..\docs" File "Skype4COM.dll" ; Register the COM server RegDLL Skype4COM.dll ;Store installation folder WriteRegStr HKCU "Software\Skype Plugin" "" $INSTDIR ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" ; Open the docs using the default (shell-assigned) browser ExecShell "open" "$INSTDIR\docs\html\index.html" SectionEnd ; Optional section (can be disabled by the user) Section "Start Menu Shortcuts" CreateDirectory "$SMPROGRAMS\Skype Plugin" CreateShortCut "$SMPROGRAMS\Skype Plugin\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 CreateShortCut "$SMPROGRAMS\Skype Plugin\Skype Plugin.lnk" "$INSTDIR\SkypePlugin.exe" "" "$INSTDIR\SkypePlugin.exe" 0 CreateShortCut "$SMPROGRAMS\Skype Plugin\Documentation.lnk" "$INSTDIR\docs\html\index.html" "" "$INSTDIR\docs\html\index.html" 0 SectionEnd ;-------------------------------- ;Descriptions ;Language strings LangString DESC_SecSkypePlugin ${LANG_ENGLISH} "Skype Plugin Installation." ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecSkypePlugin} $(DESC_SecSkypePlugin) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Uninstaller Section Section "Uninstall" Delete "$INSTDIR\Uninstall.exe" ; Unregister the COM server UnRegDLL "$INSTDIR\Skype4COM.dll" ; Delete all installed files RMDir "$INSTDIR" ; And registry entries DeleteRegKey /ifempty HKCU "Software\Skype Plugin" ; Remove shortcuts, if any Delete "$SMPROGRAMS\Skype Plugin\*.*" RMDir "$SMPROGRAMS\Skype Plugin" SectionEnd
Some points of note:
- The
RegDLL
andUnRegDLL
directives will register and unregister a COM server on your behalf; - NSIS provides “hooks” at various points of the installer lifecycle. For instance, the splash screen in shown by the .onInit handler.
- The
ExecShell
command (which seems to be a high-level wrapper around the ShellExecute function), can be used to open arbitrary files.
NSIS is a great application, and incredibly easy to pick up and use. The installers it produces are very slick looking, and can be extensively customised. It’s no wonder that this framework is now so popular.