The previous post explained how to host the GUI of Microsoft Web Platform Installer (Web PI GUI) in an own Windows Forms application. It’s nice that we can do that, but it only really makes sense when you need to perform special actions depending on the parameters determined by Web PI during installation.
Consider this: Web PI and Microsoft Web Deploy don’t seem to set the app pool default settings, especially not the .NET runtime version. So when using Web PI to install a .NET 4.0 based web application to an IIS server that has the app pool default runtime version set to “v2.0”, Web PI encounters an error and cancels installation of the web application. An administrator must set the default .NET version manually before running Web PI. In many cases, this is less than optimal.
Another example: Suppose you are installing web application A which depends on web application B. Now suppose that after installing both applications, you would like to write the address of application B in the web.config of application A. Maybe I just didn’t find any documentation of how to do it, but it seems to me that you can’t do this with Web PI.
To resolve issues like these, you might think about hosting the Web PI GUI in a custom installer application and react to events raised by Web PI during installation and read the runtime data of the product installations run by Web PI. The bad news is: Web PI does not provide a public interface for this. The good news is: these events and properties exist interally in Web PI GUI assembly Microsoft.Web.PlatformInstaller.UI.dll and we can access them via reflection. Of course, accessing internal members of other people’s assemblies is risky, because you never know when they are going to change their code. On the other hand, implementing a full blown installer like the Web PI GUI with all the parameter forms and settings dialogs is a huge load of hard work. You might consider the amount of work needed to catch up with changes in the Web PI code as much less work. Well, I guess I do.
But enough chit chat, let’s get to the code. The Web Platform Installer API provides the InstallManager class which has the events we need. But unfortunately, there is no public access to the internally used InstallManager when you use the Web PI GUI.
In the previous post, the following code line is used to create an object internally used by Web PI to resolve services that encapsulate certain functionalities.
var serviceProvider = new Microsoft.Web.PlatformInstaller.UI.UIHost(hostService, applicationOverrideFeed);
The services used in this post is Microsoft.Web.PlatformInstaller.UI.InstallerService. We need an instance of InstallerService because it has a internal property that contains the InstallManager we want. To get the InstallManager and subscribe to its events, we do the following:
// Create a service provider var serviceProvider = new Microsoft.Web.PlatformInstaller.UI.UIHost(hostService, applicationOverrideFeed); // Query service provider for internal InstallerService var type = Type.GetType("Microsoft.Web.PlatformInstaller.UI.InstallerService, Microsoft.Web.PlatformInstaller.UI"); var installerService = serviceProvider.GetService(type); // Call internal property "InstallManager" to get InstallManager var property = installerService.GetType().GetProperty("InstallManager", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); var installManager = property.GetValue(installerService, null) as InstallManager; // Subscribe to installation events installManager.InstallCompleted += OnInstallCompleted; installManager.InstallerStatusUpdated += OnInstallerStatusUpdated;
I won’t go through the code above becaus I think it is fairly simple. After executing the code above, you will get event notification during and at the end of product installations performed by Web PI. The following post will show how to get product and installation information using those event notifications.