InstallerGUI 2 Sample Explained

This is going to be a simple example of you can use the Install Manager library.

The goal:

Create a WPF application that executes installation/uninstalltion of an msi file.  It also has to be a single file application.

So the application will look like this:

It’s going to have a button that starts the installation/uninstallation, when the installation is happening a large busy indicator will animate, and a status info will inform us whether install or uninstall is executed, while on the background the status messages of the installation process are logged. Once the install/uninstall is finished the busy indicator disappears and the status message informs us that the process is finished.

Let’s get the single file application requirement out of the way first. The problem is that we may would like to use other dll-s which should ship with the exe.  ILMerge is one solution, but I went with the other option they’re referring to. That’s why there is a static constructor for the app, Note that the dll-s embedded  (in fact it is only the InstallManager.dll in this sample) are all from the Drop folder and inserted into the project as Links.

Now let’s discuss he UI, the applcation contains only one page, the MainPage. The following controls are on it, a ListBox, that is Bound to the whole page’s DataContext, the BusyIndicator (a simple animation in a grid), the Button and the TextBlock for the status. Examine the XAML for details.

We have the msi embedded also similar to the dlls .

Now Let’s see what the button click is doing.

private void btnStart_Click(object sender, RoutedEventArgs e)
 {
 btnStart.Visibility = Visibility.Collapsed;
 animGrid.Visibility = System.Windows.Visibility.Visible;
 Messages = new ObservableCollection();
 this.DataContext = Messages;
 ExtractFiles(out msiFile);
 msiInstallSession = new MsiInstallerSession(msiFile);
 PrepareInstall();
 if (msiInstallSession.IsInstalled)
 {
 tbInstallUninstall.Text = "Uninstalling...";
 AsynchUninstall();
 }
 else
 {
 tbInstallUninstall.Text = "Installing...";
 AsynchInstall();
 }

 }

The important piece starts at line 8, that is where we instantiate the session. On line 9 we subscribe to the message events.

 private void PrepareInstall()
        {

            msiInstallSession.OnMsiMessage += new EventHandler(msiInstallSession_OnMsiMessage);
            msiInstallSession.OnProgressMessage += new EventHandler(msiInstallSession_OnProgressMessage);
            msiInstallSession.OnActionStartMessage += new EventHandler(msiInstallSession_OnActionStartMessage);
            msiInstallSession.OnCommonDataMessage += new EventHandler(msiInstallSession_OnCommonDataMessage);
            msiInstallSession.OnInstallCompleted += new EventHandler(msiInstallSession_OnInstallCompleted);

        }

Then we’re checking if this msi is already installed, and we’re launching install/un-install in the background.

 private void AsynchInstall()
        {
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += (s, e) =>
            {
                msiInstallSession.Install();
            };
            bgw.RunWorkerAsync();
        }
        private void AsynchUninstall()
        {
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += (s, e) =>
            {
                msiInstallSession.UnInstall();

            };
            bgw.RunWorkerAsync();
        }

The event handlers parse the message and add it to the datacontext. We only need to take care of directing this to the UI thread from the background thread.

void msiInstallSession_OnCommonDataMessage(object sender, MsiMessageEventArgs e)
        {
            this.Dispatcher.Invoke(new Action(delegate()
            {
                Process_CommonData_Message(e);
                scwBackground.ScrollToBottom();
            }), null);

        }
private void Process_CommonData_Message(MsiMessageEventArgs e)
        {
            var msg = MsiCommonDataMessage.Parse(e.Message);
            Messages.Add(e.UIFlags + "//" + "Common Data -----" + msg.ToString());
        }

You will probably need to handle more messages and in different manner, however even these are enough for a simple installation. You can examine the documentation and other samples on how to handle messages.

Advertisements

~ by baloghp on August 15, 2012.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: