我正在使用Windows Installer 4.5新功能和WiX来生成MSI个包。
我已经创建了一个MSI链安装,以便将其他MSI包的集合安装为事务。每个包都使用新的嵌入式UI 选项,因此UI可以是WPF。到目前为止一切正常。
除了其中一个目标是显示所有安装的公共进度条。此时,我在链式安装程序中有一个进度条,但是在其他软件包开始运行之前,这个进度条达到了100%。
我已经阅读了一篇帖子 Fun with MsiEmbeddedChainer ,其中说明了我想要的东西。但我无法让它发挥作用。我想要更详细的解释和一些代码示例。
答案 0 :(得分:5)
您可以通过向安装程序发出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
}
}
}
显然,每个子安装程序都必须能够向主安装人员发出已经取得进展的信号,因此这可能需要对您的产品进行更广泛的更改。是否值得付出努力取决于你。