对 UsbDkInstaller.wxs 文件的一点说明:
<CustomAction Id="InstallDriver"
Directory="UsbDk_Directory"
ExeCommand="[UsbDk_Directory]\UsbDkInstHelper.exe i"
Execute="deferred"
Impersonate="no"
Return="ignore">
</CustomAction>
<CustomAction Id="UninstallDriver"
Directory="UsbDk_Directory"
ExeCommand="[UsbDk_Directory]\UsbDkInstHelper.exe u"
Execute="deferred"
Impersonate="no"
Return="ignore">
</CustomAction>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<Custom Action="InstallDriver" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallDriver" Before="RemoveFiles">(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>
InstallExecuteSequence 定义了安装和卸载程序时, 在某些mix标准action前后,插入标准或自定义的action;mix标准的action及执行顺序见:
每次双击一个安装包后,安装管理器会判断是否为升级安装,如果是的话则会执行两个动作:
1)卸载旧版本 - 相当于“应用和功能”窗口中,选中某个应用,点击卸载
此时会执行标准action中与卸载有关的action
2)安装新版本 - 相当于双击一个安装包,且系统中没有旧版本存在
此时会执行标准action中与安装有关的action
就我们的usbdk来说,wix标准的actions只会为我们创建或删除以下目录中的文件
C:\Program Files\UsbDk Runtime Library
如果要实现驱动程序的安装和卸载,则需要通过自定义的Custom Action来实现:
<Custom Action="InstallDriver" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallDriver" Before="RemoveFiles">(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
安装时会执行 InstallFiles 这个标准action,在这个步骤执行后,执行插入的自定义 Action: InstallDriver
<CustomAction Id="InstallDriver"
Directory="UsbDk_Directory"
ExeCommand="[UsbDk_Directory]\UsbDkInstHelper.exe i"
Execute="deferred"
Impersonate="no"
Return="ignore"> // ignore表示安装过程暂停,等待该action执行完成,但忽略执行结果
</CustomAction>
"NOT Installed" 是“是否”执行这个action的判断条件(属性):
出处:
<Custom Action="InstallDriver" After="InstallFiles">NOT Installed</Custom>
<!-- NOT Installed属性,则说明当前在执行Install操作;在执行 InstallFiles 这个action后,请执行InstallDriver这个action --><Custom Action="UninstallDriver" Before="RemoveFiles">(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
<!-- REMOVE~="ALL" 表示有REMOVE属性且具体值为"ALL", ~表示忽略大小写;表明此时在执行Uninstall或者Upgrade操作 -->
<!-- NOT UPGRADINGPRODUCTCODE 表示非升级安装的情况 -->
<!-- 两者AND,表示从应用列表中点击卸载,只有这种情况时,在RemoveFiles这个标准action前,执行自定义action: UninstallDriver -->
上面表示了,当仅安装时,某个时机执行 InstallDriver; 当仅卸载时,某个时机执行 UninstallDriver
那个当升级安装时,什么时候卸载呢?
升级安装时,安装管理器会先执行卸载操作,此时因为不满足条件,没有自定义的action被执行,即只是删除 C:\Program Files\UsbDk Runtime Library 目录;
安装管理器紧接着执行安装操作,此时满足执行 InstallDriver的条件,于是会调用 “UsbDkInstHelper.exe i”
在 UsbDkInstHelper.exe 的安装流程中,我们做了特殊的处理,会判断UsbDk的service是否存在,如果存在则会先执行Uninstall的操作,然后再执行Install的操作,这是我们有意为之的。
.wxs文件中,还有一点需要注意,UPGRADINGPRODUCTCODE属性是如何产生的?
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<Custom Action="InstallDriver" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallDriver" Before="RemoveFiles">(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>
UPGRADINGPRODUCTCODE属性是windows安装管理器在RemoveExistingProducts这个标准动作中设置的;RemoveExistingProducts这个动作需要我们在 <InstallExecuteSequence/> 进行设置。
出处:https://learn.microsoft.com/en-us/windows/win32/msi/upgradingproductcode