This article presents the most important part of SharpSetup solution that we have seen on screenshots in previous article. It describes how WiX generated MSI database is tied together with Windows Forms (WinForms) based GUI. It shows how Gui project is structured and how you can create custom UI that fits your needs.
Gui project is a Windows application project with several important characteristics:
- it references SharpSetup library,
- it has custom Program.cs file with code for installer setup and error handling,
- it has one main form (SetupWizard.cs) which takes care of handling Next, Back, Cancel, Finish buttons,
- it has multiple step controls that are embedded into main form.
SharpSetup library is the core of SharpSetup, an interface between managed GUI and unmanaged Windows Installer API. The library provides you with two major non-GUI classes: MsiDatabase for accessing *.msi files (MSI databases) and MsiConnection for interacting with Windows Installer service. It is worth noting that MsiConnection class is a singleton (only one instance can exist per process). This is a limitation imposed by Windows Installer itself as it allows only one installation at a time system-wide.
Other non-GUI classes include MsiException, MsiHelper, SetupHelper, Feature, etc. These are responsible for communicating Windows Installer errors to your code, bootstrapping uninstaller so that it may remove all program components, formatting numbers as disk space values (in KB, MB), communicating feature name, states and levels, and various other small but useful tasks.
The second major group of classes are GUI classes: controls and dialogs. SharpSetup allows you to use controls such as FeatureTree control, PrerequisiteList control, InstallationModeSelector control, InstllationProgress control, DestinationPath control, DiskCostList control and SimpleDiskCostBox control. The names are pretty self explanatory. It is also very easy to use those controls: you just place them on a dialog and the control automatically uses data from open MsiConnection to display information to the user.
Another group of GUI elements are dialog related classes. WizardBase class is responsible for managing main installer for events such as changing step, canceling instalaltion and keeping history of previous steps. ModernWizard is responsible for major GUI elements such as Next, Back, Cancel and Finish buttons. ModernWizard is the parent class of SetupWizard class - the main UI class in your installer solution. However, if you do not like the default layout of this dialog you may inherit directly from WizardBase (if you still want to use WinForms based GUI) or create your GUI from scratch.
The default GUI (ModernWizard class) uses steps to interact with the user. Technically speaking steps are custom controls that inherit from StepBase or one of StepBase derived controls: ModernStep (bare step that may be used with ModernWizard), ModernInfoStep (step with image on the left and white background on the right) or ModernActionStep (step with gray background and white bar on top). Which one you choose as base class for your dialog is entirely up to you. The fact that steps are custom controls allows them to be visually designed in Visual Studio forms and controls designer. Steps have various properties such as Title, Subtitle, Type (None, Last, Transitionary, TransitionaryOnetime) and may react to various types of events: OnBack, OnNext, OnFinish, Entering and Entered which can be designed using Visual Studio as well (see screenshot).
While inheriting ModernStep, ModernInfoStep or ModernActionStep is not a though task, creating installer GUI may be even easier. SharpSetup provides you with dialog templates for common use scenarios. For example almost every installer will have WelcomeStep and FinishStep. As you can see a freshly generated installer solution already has those steps. If you want to add more steps you may right-click on Gui project then select New item... command from Add submenu. In the Add New Item dialog choose SharpSetup on the left and then select one of the dialog templates on the right (sample steps: License dialog, Prerequisite check dialog, Feature selection dialog, Installation ready dialog, Installation type dialog, etc.). After the dialog is created you have to hook it into wizard sequence so that it is displayed at the right moment. To do so, go to SetupWizard.LifecycleAction method and add the step in the correct sequence (install, uninstall, reinstall, upgrade, etc.).
The installer in action
And here is how it all fits together to create a working installer.
Previous in series: First SharpSetup screenshots
Next in series: The Package project (WiX based)