Implement a fancy UI for nsis

We have known windows standard installation UI for years, and the good thing is we are so fimilar with the UI, we can even click blindly without meeting problem. However, client applications are getting more beautiful UIs, should we apply the same thing to the client installers?

Basiclly, that’s all. In another side, the setup work is quite different in different applications: some software may depend resources from network, it will do download during installation; some software may want to display information from a website, it will embed a web browser inside installer UI.

Nsis is a good installation system which supports kinds of plugins. However, it requires a dev to know the nsis internal deeply, especially when a dev wants to implement a UI completely different from the standard installation UI.

As the result, we can see numbers of dev do like this:

1. it implements a fancy UI in C++, employing kinds of UI library

2. it has to implement decompression logic, usually from a zip file

3. it has to implement a packer that prepares the zip file, and maybe append the zip file into the installer exe.

4. it has to implement kinds of setup code so that the installer can do the real installation work, for example, create service, create shortcut, etc.

Is there any shortcoming if we do like this?

Besides the UI, actually most of the work are re-inventing the wheel, they are already part of an existing installation system or a plugin of that installation system. More still, an installer may keep changing inside a product lifecycle, and most of them are only to change installer UI layout, or to adjust minor installation flow. It’s a nightmare to handle these in C++.

Back to Nsis, we should take a look of its existing installation flow before continuing the journey.

So far, we have bridged a ui message loop into nsis ui thread. Next, we need to enable the the scripting ability for the UI, so that we can use script to handle UI event.

Windows GUI is event driven, uses message queue to mange events. Similar to Windows OS, UI libraries are also event driven, but usually use callbacks to allow applications to handle events, so they provide registration functions. Take the libray I’m using as an example:

The most paramter “extra” exposes a usefull function “ExecuteCodeSegment”, it allows C++ code to call nsis script. Before we can call script code, we need a function inside script which provides the ablity to get a function address inside nsis script.

GetFunctionAddress

user_var(output) function_name

Gets the address of the function and stores it in the output user variable. This user variable then can be passed to Call or Goto. Note that if you Goto an address which is the output of GetFunctionAddress, your function will never be returned to (when the function you Goto’d to returns, you return instantly).

WIN_ID represents the native C++ windows handle(instance), CTRL_ID represents the widget id which is defined in a xml.

Although the code pieces attached here is few, we do have finished introducing how to handle event from scripts, and how to control UI elements from scripts. Please allow me attach part of the installer code, so that we can have a global view of the whole installer.