使用嵌入式UI安装一系列嵌入式MSI程序包-显示公共进度栏
时间:2020-03-06 14:55:38 来源:igfitidea点击:
我正在使用Windows Installer 4.5的新功能和WiX来生成MSI程序包。
我创建了一个MSI链安装,以便将其他MSI软件包的集合作为事务安装。每个软件包都使用新的"嵌入式UI"选项,因此UI可以是WPF。到目前为止一切正常。
目标之一是为所有安装显示一个公共进度栏。目前,我在链安装程序中有一个进度条,但是在其他软件包开始运行之前,这个进度条达到了100%。
我已经阅读了一篇与MsiEmbeddedChainer一起玩的文章,指出我想要的东西可以实现。但是我无法使它正常工作。我想要更详细的解释,也许还需要一些代码示例。
解决方案
我们可以通过向安装程序发出" INSTALLMESSAGE_PROGRESS"消息来手动控制进度条的状态。详细信息可以在这里找到:
http://msdn.microsoft.com/en-us/library/aa370354.aspx
特别是,我们将需要自定义操作来管理状态栏(由它负责对MsiProcessMessage
进行适当的调用。我建议我们也使用它来生成子安装程序。这是一些伪代码。说明我的想法:
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); }
主要的不利方面是进度条将以某种不稳定的方式进行。如果我们真的想花哨并使其更流畅,则可以启动一个单独的"侦听器"线程,该线程将等待子安装程序的更新以对进度条进行更细粒度的增量。就像是:
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 } } }
显然,每个子安装程序都必须能够向主安装程序发出已取得进展的信号,因此这可能需要对整个产品进行更广泛的更改。是否值得付出努力取决于我们。