Install a chain of built-in MSI packages, each of which uses a built-in indication of the progress of the user interface.

I am using Windows Installer 4.5 new features and WiX to create MSI packages .

I created an MSI network setup to set up a collection of other MSI packages as a transaction. Each package uses a new built-in interface, so the user interface can be WPF . So far, everything is working fine.

Except for one goal, it would display a common progress bar for all installations. At this point, I have a progress bar in the chain installer, but this level reaches 100% before other packages run.

I read a post, Fun with MsiEmbeddedChainer , which says what I can achieve. But I canโ€™t make it work. I would like more detailed explanations, and possibly some code examples.

+6
windows-installer wix
source share
1 answer

You can manually control the progress bar status by sending INSTALLMESSAGE_PROGRESS messages to the installer. Details can be found here:

http://msdn.microsoft.com/en-us/library/aa370354.aspx

In particular, you will need a custom action to control the status bar (this will be responsible for making the corresponding calls to MsiProcessMessage . I recommend that you also use it to create tweaks. This is some pseudo code to illustrate what I mean:

 LONG LaunchSubinstallersCA(MSIHANDLE current_installer) { // Initialize the progress bar range and position MsiProcessMessage(current_installer, reset_message); // see MSDN for details for each (subinstaller in list_of_installers) { launch subinstaller; // see MSDN for details // Update the progress bar to reflect most recent changes MsiProcessMessage(current_installer, increment_message); // see MSDN for details } return (result); } 

The main downside is that the progress bar will be somewhat volatile. If you really wanted to get the fantasy and make it smoother, you can start a separate thread of the โ€œlistenerโ€, which will wait for updates from the sub-installer to make fine-grained increments for the progress bar. Something like:

 LONG LaunchSubinstallersCA(MSIHANDLE current_installer) { // Initialize the progress bar range and position MsiProcessMessage(current_installer, reset_message); // see MSDN for details launch_listener_thread(); // launches listener_thread_proc (see below) for each (subinstaller in list_of_installers) { launch subinstaller; // see MSDN for details } tell_listener_thread_to_stop(); optionally_wait_for_listener_thread_to_die(); return (result); } void listener_thread_proc() { // Loop until told to stop while (!time_for_me_to_stop) { // Listen for update from sub-installer timed_wait_for_update(); // probably required IPC, perhaps a named event? // Only update the progress bar if an update message was actually received if (!timeout) { // Update the progress bar to reflect most recent changes MsiProcessMessage(current_installer, increment_message); // see MSDN for details } } } 

Obviously, each installer would have to signal to the main installer that progress has been made, so this would potentially require more extensive changes to your product. Whether itโ€™s worth the effort is up to you.

+5
source share

All Articles