Wix安装程序不会覆盖以前版本的可执行文件



我有一个非常简单的安装程序-将一个dll复制到Program Files子文件夹中,并用regsvr32.exe注册它。效果很好,但如果安装了旧版本的dll,"修复"不会覆盖现有的dll。dll已签名,其版本(内部版本)号始终递增(例如2.0.0.123->2.0.0.124)。

查看之前类似的帖子,我添加了RemoveExistingProducts,并将ProductId指定为"*"。卸载然后安装新版本工作正常,但我真的需要修复来更新现有的dll。

我还有什么需要做的吗?

谢谢!

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
When creating a new install for the next version, these fields must be modified
-->
<?define ProductVersion = "2.0.00" ?>
<?define ProductId64 = "*" ?>
<?define ProductId32 = "*" ?>
<?define PackageId   = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>

<!-- Product name as you want it to appear in Add/Remove Programs-->
<?if $(var.Platform) = x64 ?>
<?define ProductName = "XYZ (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define ProductId = "$(var.ProductId64)" ?>
<?define MainDllName = "XYZ64.dll" ?>
<?define MainDllSource = "....binWin64ReleaseXYZ64.dll" ?>
<?else ?>
<?define ProductName = "XYZ (32 bit)" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define ProductId = "$(var.ProductId32)" ?>
<?define MainDllName = "XYZ.dll" ?>
<?define MainDllSource = "....binWin32ReleaseXYZ.dll" ?>
<?endif ?>

<?define UpgradeCode = "{C3763742-7C1C-4AB7-A404-F030B7550E97}" ?>

<Product Id="$(var.ProductId)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="Advanced Messaging Systems LLC" UpgradeCode="$(var.UpgradeCode)">
<Package Id="$(var.PackageId)" InstallerVersion="200" Compressed="yes" Description="XYZ Installer package"  InstallPrivileges="elevated"/>
<!-- No restore point  -->
<Property Id="MSIFASTINSTALL" Value="3" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
<Directory Id="INSTALLLOCATION" Name="XYZ">
<Component Id="XYZDll" Guid="E2CBEE41-6C0E-4A84-95C1-7282747B4A3D">
<File Id='MainDll' Name="$(var.MainDllName)" DiskId='1' Source="$(var.MainDllSource)" SelfRegCost="0" />
<!-- TODO: Insert files, registry keys, and other resources here. -->
</Component>
</Directory>
</Directory>
</Directory>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<!-- Note: Custom actions to install/uninstall the dll using regsvr32.exe -->
<CustomAction Id="RegisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s "[INSTALLLOCATION]$(var.MainDllName)"'
Return="check">
</CustomAction>
<CustomAction Id="UnregisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s /u "[INSTALLLOCATION]$(var.MainDllName)"'>
</CustomAction>

<Feature Id="ProductFeature" Title="XYZ" Level="1">
<ComponentRef Id="XYZDll" />
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
<InstallUISequence>
<Custom Action="WixCloseApplications" Before="AppSearch"/>
</InstallUISequence>
<InstallExecuteSequence>
<!-- Uninstall previous version before installing this one. -->
<RemoveExistingProducts Before="InstallInitialize"/>

<SelfRegModules/>
</InstallExecuteSequence>
<Icon Id="XYZ.ico" SourceFile="..GraphicsXYZ.ico"/>
<Property Id="ARPPRODUCTICON" Value="XYZ.ico" />
<!-- UI -->
<UIRef Id="WixUI_InstallDir"/>
<UIRef Id="WixUI_ErrorProgressText" />
<WixVariable Id="WixUILicenseRtf" Value="..EULAlicense.rtf" />
<WixVariable Id="WixUIBannerBmp"  Value="..Graphicsbanner.jpg" />
<WixVariable Id="WixUIDialogBmp"  Value="..Graphicslogo.jpg" />

<!-- End UI -->
</Product>
</Wix>

更新。修改升级条目后,以下内容对我有效:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
When creating a new install for the next version, these fields must be modified
-->
<?define ProductVersion = "2.0.4" ?>
<?define ProductId64 = "*" ?>
<?define ProductId32 = "*" ?>
<?define PackageId   = "*" ?>

<!-- Product name as you want it to appear in Add/Remove Programs-->
<?if $(var.Platform) = x64 ?>
<?define ProductName = "XYZ (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define ProductId = "$(var.ProductId64)" ?>
<?define MainDllName = "XYZ64.dll" ?>
<?define MainDllSource = "....binWin64ReleaseXYZ64.dll" ?>
<?else ?>
<?define ProductName = "XYZ (32 bit)" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define ProductId = "$(var.ProductId32)" ?>
<?define MainDllName = "XYZ.dll" ?>
<?define MainDllSource = "....binWin32ReleaseXYZ.dll" ?>
<?endif ?>

<?define UpgradeCode = "{C3763742-7C1C-4AB7-A404-F030B7550E97}" ?>

<Product
Id="$(var.ProductId)"
Name="$(var.ProductName)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="Advanced Messaging Systems LLC"
UpgradeCode="$(var.UpgradeCode)"
>
<Package Id="$(var.PackageId)"
InstallerVersion="200"
Compressed="yes"
Description="XYZ Installer package"
InstallPrivileges="elevated"
/>
<!-- No restore point  -->
<Property Id="MSIFASTINSTALL" Value="3" />

<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>

<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
<Directory Id="INSTALLLOCATION" Name="XYZ">
<Component Id="XYZDll" Guid="E2CBEE41-6C0E-4A84-95C1-7282747B4A3D">
<File Id='MainDll' Name="$(var.MainDllName)" DiskId='1' Source="$(var.MainDllSource)" SelfRegCost="0" />
<!-- TODO: Insert files, registry keys, and other resources here. -->
</Component>
</Directory>
</Directory>
</Directory>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<!-- Note: Custom actions to install/uninstall the dll using regsvr32.exe -->
<CustomAction Id="RegisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s "[INSTALLLOCATION]$(var.MainDllName)"'
Return="check">
</CustomAction>
<CustomAction Id="UnregisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s /u "[INSTALLLOCATION]$(var.MainDllName)"'>
</CustomAction>

<Feature Id="ProductFeature" Title="XYZ" Level="1">
<ComponentRef Id="XYZDll" />
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
<InstallUISequence>
<Custom Action="WixCloseApplications" Before="AppSearch"/>
</InstallUISequence>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<SelfRegModules/>
</InstallExecuteSequence>
<Icon Id="XYZ.ico" SourceFile="..GraphicsXYZ.ico"/>
<Property Id="ARPPRODUCTICON" Value="XYZ.ico" />
<!-- UI -->
<UIRef Id="WixUI_InstallDir"/>
<UIRef Id="WixUI_ErrorProgressText" />
<WixVariable Id="WixUILicenseRtf" Value="..EULAlicense.rtf" />
<WixVariable Id="WixUIBannerBmp"  Value="..Graphicsbanner.jpg" />
<WixVariable Id="WixUIDialogBmp"  Value="..Graphicslogo.jpg" />

<!-- End UI -->
</Product>
</Wix>

如果您想要大升级,请从WiX MajorUpgrade元素开始。升级的一般规则是:

  1. 与旧产品不同的ProductCode和PackageCode
  2. 在前三个字段中的某个位置递增ProductVersion
  3. 与旧产品相同的UpgradeCode
  4. 做一些事情(比如Wix MajorUprade或升级元素)来确保你有一个适当的升级
  5. 按用户安装不会升级按系统安装,反之亦然

在最初的情况下,未能遵守规则1和2意味着Windows认为已经安装了相同的产品,并进入修复模式。这应该是你的第一个警告,因为重大升级看起来像是新安装,而不是修复。如果您在Programs&特征它意味着这4个要求中的一个或多个没有得到满足。如果你得到"这个产品的另一个版本已经安装",这意味着你没有遵循规则1,与安装的产品相比,行为的变化是关于ProductCode和PackageCode值的。

我很惊讶这一行实际上被Wix编译器链接器允许:

<?define PackageId   = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>

如果这真的有效并通过了,我还没有测试过,这意味着你的包有一个硬编码的包id。我以为Wix可以防止这个问题?也许是这样?我们应该与Wix社区核实是否允许硬编码的包guid有任何意义。我想这对于调试和测试来说可能是必要的,但至少应该有一个编译器警告。

包GUID的理念是,它对于每个编译的MSI文件都应该是唯一的它只是用来唯一地识别一个文件根据定义,Windows安装程序将把具有相同包guid的两个不同MSI文件视为同一文件。导致各种x文件问题。因此包GUID应该始终自动生成,因为它只是被认为是唯一的。请先尝试解决此问题,以检查这是否解决了您的整体问题。将其设置为*。

我的建议是自动生成包id产品id置硬编码升级代码。升级代码可识别">产品系列",无论语言和版本如何,都可用于识别产品的任何实例。对于64位和32位的设置,使用单独的升级代码可能会很有用,因为在某些系统上可以同时安装这两个版本。

您可能还想取消使用regsvr32.exe进行自注册,并从dll中提取COM数据以获得正确的MSI支持:MSI register dll-自注册被认为是有害的。也许还可以检查一下:使用WiX注册ActiveX exe服务器(如果Heat不工作,请检查RegSpy2)。

还请注意,您可以从Wix xml文件中省略许多源属性,并依赖Wix默认值,而不是硬编码值。

关于GUID和文件替换的一些进一步详细信息:

  • 是否更改wix中的组件GUID
  • MSI引用计数:两个产品安装相同的MSI
  • 强制升级在初始安装过程中修改的文件
  • msi版本号
  • 文件版本控制规则
  • 替换现有文件(图表,两个文件都有版本)
  • Aaron Stebner的简明英文文件版本控制描述

简短的回答(另一个变得太乱了):试着删除这一行,并通过将其设置为"*"来自动生成包ID:

<?define PackageId   = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>

请注意,在卸载所有以前的MSI生成后,必须停止使用它们。这是由于硬编码的包guid有故障,这可能会导致不可预测和不可预见的问题。

相关内容

最新更新