Install a chain of embedded MSI packages each using an embedded UI - display common progress bar

前端 未结 1 551
北海茫月
北海茫月 2021-02-09 16:23

I\'m using Windows Installer 4.5 new features and WiX to generate MSI packages.

I have created an MSI chain installation in order to install a collection of other MSI pa

1条回答
  •  抹茶落季
    2021-02-09 16:44

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

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

    In particular, you'll need a custom action to manage the status bar (it is what will be responsible for making the appropriate calls to MsiProcessMessage. I recommend that you also use it to spawn the sub-installers. Here is some pseudocode to illustrate what I have in mind:

    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 down-side is that the progress bar will progress in a somewhat choppy fashion. If you really wanted to get fancy and make it smoother, you could launch a separate "listener" thread that would wait for updates from the sub-installer to make finer-grained increments to 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 sub-installer would have to be able to signal the main installer that progress has been made, so this will potentially require more extensive changes across your product. Whether or not that is worth the effort is up to you.

    0 讨论(0)
提交回复
热议问题