其他安装正在进行挂起我的Wix安装

时间:2018-05-03 15:07:43

标签: wix windows-installer wix3.11

我正在创建一个WIX安装程序引导程序(在msipackage上使用DisplayInternalUI="yes"),但是当同时发生其他安装时它会挂起。

如果我使用msiexec自行运行MSI文件,则会出现Windows安装程序错误 "Another installation is in progress"消息(即1500 MSI错误消息) - 我认为这是挂起我的安装。

因此,我正在做的是看看我是否可以在用户按下“安装”按钮后(即_MSIExecute mutex之前)锁定ProgressDlg。如果我可以锁定Mutex,则没有其他正在进行的安装 - 因此可以安全地继续安装(即执行阶段)。如果不是,安装程序会显示取消按钮(而不显示其他按钮) - 因此安装将不会继续。

我想知道是否有办法阻止"Another installation is in progress"错误消息(和其他消息)挂起安装程序。

3 个答案:

答案 0 :(得分:1)

没有MSI并发 :为什么还有“同时”发生其他安装 - 或者换句话说同时发生?在谈到WiX Burn bootstrappers时,我不是太过于训练有素,但我想知道MSI中是否包含任何启动其他MSI安装的自定义操作? MSI包不允许这样做。您不能同时运行两个并发InstallExecuteSequences。因此,您无法在InstallExecuteSequence内启动MSI。有些人试图从InstallUISequence启动安装,由于许多原因,这也是非常不可取的 - 首先,当设置以静默模式运行时,它根本不会运行。我还怀疑提升的潜在问题,如果您设置检查自定义操作的退出代码,以及那种东西,意外的安装失败。它总是在变换。要记住的基本经验法则是:自定义操作绝不能启动其他MSI安装 WiX Burn bootstrapper 基本上是专门存在的,允许您按顺序运行MSI文件 - 而不是同时运行 - 但它也更多:它是一个组合的bootstrapper,chainer,downloader等......

Mutex :强有力的话语,但如果你知道什么对你有好处,你就会远离MSI互斥体。救你自己! :-)。 MSI是一种反击的技术,如果你参加战斗,你将会真正对抗风车。这就是我所能说的一切来警告你。除非您遵循基本规则,否则无法处理,在这种情况下,一次运行一个安装程序。 WiX家伙可以处理它 - 留给他们 - 并使用他们的工具(WiX Burn)。虽然我不清楚技术细节,但它们肯定会实现完全符合您描述的功能(检查系统是否已准备好安装)。

暂停安装 :在您可以安装MSI文件之前,您的系统上还可能需要撤消已暂停的安装。您可以尝试安装另一个MSI文件,看看它是否正确运行?我不是100%确定这是正确的链接,但您也可以尝试:Fix problems that block programs from being installed or removed

答案 1 :(得分:0)

更新:关于_MSIExecute Mutex。有关使用QueryServiceStatusEx检查当前Windows Installer状态的技术信息,请参阅底部。希思·斯图尔特提出了另一种方式(sample C++ code)。

此外,一些预先存在的相关答案:

首先对手头的问题提出一些意见(虚拟更新和待定重启):

正在进行的Windows更新 :如果您正在处理在后台执行Windows更新并且MSI安装无法运行的情况,那么它在检查系统重启是否待决时,WiX Burn可能会挂起。我之前见过这样的问题(参见"技术问题"下面)。

真正修复 :如果是这种情况唯一真正的修复是让Windows更新完成,然后重新启动并保留新的虚拟机状态,然后安装您的包。 这是唯一理智的解决方案 - 在我看来。不是你想听到的: - )。

脏"修复" :我想您也可以停止Windows Update服务以阻止安装Windows更新,但我的猜测是你的如果你这样做,虚拟将最终被恶意软件感染,然后你就会出现这样一种可怕的情况,即你可能会意外地在你的虚拟中持续存在恶意软件,然后定期复活并且安全软件(通常不扫描虚拟软件)不会检测到恶意软件。这可能是现存最严重的恶意软件向量之一,因为它很难根除它并发现它(与只读媒体上的恶意软件和检查到源代码控制系统的恶意软件相同 - 可能没有一种简单的方法可以获得摆脱它)。 善意的建议(那种从未想过的东西 - 我们都生活在现实中):请不要在没有适当考虑后果的情况下禁用虚拟Windows Update 。在整个企业范围内我永远不会允许这样的事情 - 只有具有超出正常测试需求的特定用户的例外情况 - 并且虚拟用户将被定期进行强制恶意软件检查。这提醒我检查哪些安全软件可以正确扫描脱机虚拟。更多研究要做。有趣的是,编写stackoverflow答案总是教会我自己做不好的事情!不好: - )。

技术问题 :关于技术问题。我之前看到过WiX Burn挂起的问题,因为它特意试图避免在正在更新的系统上安装:

也许检查链接答案中的那个小VBScript(或者你想要的任何语言的等效COM调用)是否会告诉你系统是否还没有准备安装?

简单黑客? :未经过验证,但也许您可以检查注册表项/值(不确定这是值还是密钥):{{ 1}} - 据我所知,它应该存在以指示活动的Windows Installer会话。我认为这比尝试处理互斥锁和其他操作系统基础更好。

奇怪的是,我不知道有任何MSI API calls会告诉您是否存在活动的安装会话(互斥集)。我唯一能看到的是一个Win32函数(即不是COM自动化):MsiBeginTransaction(最近添加到MSI API,仅4.5)。

还有:MSDN: _MSIExecute Mutex - 建议使用QueryServiceStatusEx并检查HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer : InProgress的值是否为dwControlsAccepted。我从来没有尝试过。坦率地说,我会尝试检查上面的注册表项。

答案 2 :(得分:0)

如果主要关注Windows Update,那么您将使用Windows Update代理API来检测是否有正在进行的更新。在尝试安装MSI之前,我认为您需要从自己的引导程序运行它。一般的C ++想法如下:

#include "stdafx.h" 
#include <wuapi.h> 
#include <iostream> 
#include <ATLComTime.h> 
#include <wuerror.h> 
using namespace std; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
HRESULT hr; 
hr = CoInitialize(NULL); 
IUpdateSession* iUpdate; 
IUpdateSearcher* searcher; 
IUpdateInstaller* iInstaller; 
ISearchResult* results; 
BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1 or 
IsPresent=1"); 
hr = CoCreateInstance(CLSID_UpdateInstaller, NULL, 
CLSCTX_INPROC_SERVER, IID_IUpdateInstaller, (LPVOID*)&iInstaller); 
VARIANT_BOOL Busy; 
hr = iInstaller->get_IsBusy(&Busy); 

基本上,IsBusy属性会告诉您是否正在进行更新。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa386502(v=vs.85).aspx

讨论主题在这里:

http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Windows-Updates-either-pending-or-running-causes-our-installs-to-fail-td7598536.html

还有一个更好的代码示例。我不知道托管代码接口或内置WiX支持。