Rob*_*ner 7 windows-installer wix
对于我产品的新版本 v1.9.0,我创建了一个新的 MSI 安装程序。该应用程序的先前版本是 v1.7.0。
卸载旧版本然后安装新版本工作正常。
但是当我尝试使用 v1.9.0 安装程序更新旧版本时,正好缺少一个文件 ( NLog.dll )。所有其他文件都被复制得很好。
我正在使用 heat.exe 为我的应用程序的所有依赖项创建组件。因此NLog.dll的处理方式与其他所有文件完全相同,但它是唯一显示这种奇怪行为的文件。
这些是此文件的相关日志片段。
第 5174 行:
MSI (s) (E4:1C) [17:12:42:343]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
第 37733 行:
MSI (s) (E4:1C) [17:13:12:252]: Executing op: FileRemove(,FileName=NLog.dll,,ComponentId={53AAD98D-AFDB-4D70-ADCC-5305C3174ED5})
RemoveFiles: File: NLog.dll, Directory: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\
MSI (s) (E4:1C) [17:13:12:260]: Verifying accessibility of file: NLog.dll
MSI (s) (E4:1C) [17:13:12:264]: Note: 1: 2318 2:
MSI (s) (E4:1C) [17:13:12:267]: Note: 1: 2318 2:
Run Code Online (Sandbox Code Playgroud)
第 50386 行:
MSI (s) (E4:DC) [17:13:22:442]: Executing op: ComponentRegister(ComponentId={D4B31A07-4F5F-4DAA-8280-9A782110477A},KeyPath=C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll,State=3,,Disk=1,SharedDllRefCount=2,BinaryType=0)
1: {C2F509F4-A1F9-4377-89FE-59B4DB664FB7} 2: {D4B31A07-4F5F-4DAA-8280-9A782110477A} 3: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll
MSI (s) (E4:DC) [17:13:22:442]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
为了进行比较,这里是一些随机其他文件 ( NLog.Extensions.Logging.dll )的日志片段,这些文件按预期更新。
第 5173 行:
MSI (s) (E4:1C) [17:12:42:342]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
第 37738 行:
MSI (s) (E4:1C) [17:13:12:267]: Executing op: FileRemove(,FileName=NLog.Extensions.Logging.dll,,ComponentId={2CE3E451-CBCA-4D6A-953A-0EEC1F23FE33})
RemoveFiles: File: NLog.Extensions.Logging.dll, Directory: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\
MSI (s) (E4:1C) [17:13:12:269]: Verifying accessibility of file: NLog.Extensions.Logging.dll
MSI (s) (E4:1C) [17:13:12:272]: Note: 1: 2318 2:
MSI (s) (E4:1C) [17:13:12:276]: Note: 1: 2318 2:
Run Code Online (Sandbox Code Playgroud)
第 50389 行:
MSI (s) (E4:DC) [17:13:22:442]: Executing op: ComponentRegister(ComponentId={0DFB8E8D-FD31-430F-A84B-C21D7BCB296B},KeyPath=C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll,State=3,,Disk=1,SharedDllRefCount=2,BinaryType=0)
1: {C2F509F4-A1F9-4377-89FE-59B4DB664FB7} 2: {0DFB8E8D-FD31-430F-A84B-C21D7BCB296B} 3: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll
MSI (s) (E4:DC) [17:13:22:442]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
第 51640 行:
MSI (s) (E4:DC) [17:13:23:148]: Executing op: FileCopy(SourceName=c7dqtb1j.dll|NLog.Extensions.Logging.dll,SourceCabKey=filC5C20BE40C004EEC9809A0196347239A,DestName=NLog.Extensions.Logging.dll,Attributes=512,FileSize=24064,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=1.3.0.804,Language=0,InstallMode=58982400,,,,,,,)
MSI (s) (E4:DC) [17:13:23:149]: File: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll; To be installed; Won't patch; No existing file
MSI (s) (E4:DC) [17:13:23:149]: Source for file 'filC5C20BE40C004EEC9809A0196347239A' is compressed
InstallFiles: File: NLog.Extensions.Logging.dll, Directory: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\, Size: 24064
Run Code Online (Sandbox Code Playgroud)
如您所见,NLog.dll和其他文件的前三个片段看起来几乎相同。但是在NLog.dll的情况下,文件实际被复制的最后一部分只是丢失了。
日志中没有任何内容可以解释(对我而言)为什么没有复制NLog.dll。
我不知道这是否有任何相关性,但这里是原始安装中这两个文件的相关日志片段。也许这些很重要,因为它们在原始安装期间拥有的 ID。
第 5316 行(NLog.dll):
MSI (s) (E4:94) [17:11:14:734]: Executing op: ComponentRegister(ComponentId={53AAD98D-AFDB-4D70-ADCC-5305C3174ED5},KeyPath=C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll,State=3,,Disk=1,SharedDllRefCount=0,BinaryType=0)
1: {D6410853-B366-4D05-A1A3-93FC3EFF982A} 2: {53AAD98D-AFDB-4D70-ADCC-5305C3174ED5} 3: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll
MSI (s) (E4:94) [17:11:14:734]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
第 5319 行(NLog.Extensions.Logging.dll):
MSI (s) (E4:94) [17:11:14:734]: Executing op: ComponentRegister(ComponentId={2CE3E451-CBCA-4D6A-953A-0EEC1F23FE33},KeyPath=C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll,State=3,,Disk=1,SharedDllRefCount=0,BinaryType=0)
1: {D6410853-B366-4D05-A1A3-93FC3EFF982A} 2: {2CE3E451-CBCA-4D6A-953A-0EEC1F23FE33} 3: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll
MSI (s) (E4:94) [17:11:14:735]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
Run Code Online (Sandbox Code Playgroud)
第 19183 行(NLog.dll):
MSI (s) (E4:94) [17:11:17:881]: Executing op: FileCopy(SourceName=NLog.dll,SourceCabKey=fil3052FED1115C64C0B25CEB4ED20F217C,DestName=NLog.dll,Attributes=512,FileSize=422400,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=5.0.0.0,Language=0,InstallMode=58982400,,,,,,,)
MSI (s) (E4:94) [17:11:17:882]: File: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.dll; To be installed; Won't patch; No existing file
MSI (s) (E4:94) [17:11:17:882]: Source for file 'fil3052FED1115C64C0B25CEB4ED20F217C' is compressed
InstallFiles: File: NLog.dll, Directory: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\, Size: 422400
Run Code Online (Sandbox Code Playgroud)
第 31615 行(NLog.Extensions.Logging.dll):
MSI (s) (E4:94) [17:11:22:509]: Executing op: FileCopy(SourceName=c7dqtb1j.dll|NLog.Extensions.Logging.dll,SourceCabKey=filC5C20BE40C004EEC9809A0196347239A,DestName=NLog.Extensions.Logging.dll,Attributes=512,FileSize=8704,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=1.0.0.0,Language=0,InstallMode=58982400,,,,,,,)
MSI (s) (E4:94) [17:11:22:509]: File: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\NLog.Extensions.Logging.dll; To be installed; Won't patch; No existing file
MSI (s) (E4:94) [17:11:22:509]: Source for file 'filC5C20BE40C004EEC9809A0196347239A' is compressed
InstallFiles: File: NLog.Extensions.Logging.dll, Directory: C:\Program Files (x86)\Cisco\DiagnosticBridge\bin\, Size: 8704
Run Code Online (Sandbox Code Playgroud)
为了收集依赖项,我像这样运行heat.exe:
"%WIX%\bin\heat" dir "$(ProjectDir)\obj\PublishOutput" -dr BinFolder -ke -srd -sreg -cg MyComponentGroup -var var.TempPublishDir -gg -out "$(ProjectDir)\obj\MyContent.wxs"
Run Code Online (Sandbox Code Playgroud)
生成的组件如下所示:
<Component Id="cmpE15B2B75697ADA78CA21A063FF464A7F" Directory="BinFolder" Guid="{876C7C40-4FD9-464E-9282-5CE83B56C4C9}">
<File Id="fil3052FED1115C64C0B25CEB4ED20F217C" KeyPath="yes" Source="$(var.TempPublishDir)\NLog.dll" />
</Component>
<Component Id="cmpF5B8522DF5AB91BD2DBBA73CBCD944B8" Directory="BinFolder" Guid="{EFB396C4-4F10-4C1B-92FB-75D5C616A708}">
<File Id="filC5C20BE40C004EEC9809A0196347239A" KeyPath="yes" Source="$(var.TempPublishDir)\NLog.Extensions.Logging.dll" />
</Component>
Run Code Online (Sandbox Code Playgroud)
以及产品定义的相关部分:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="xxx" Language="1033" Version="1.9.0.0" Manufacturer="xxx" UpgradeCode="ab9f8a5a-aa60-4327-9299-3f928136a6e4">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
</Product>
</Wix>
Run Code Online (Sandbox Code Playgroud)
有一个非常类似的问题在这里。重要的似乎是RemoveExistingProducts尽可能早地执行。如果我理解这个正确,使用MajorUpgrade指令(我用),默认为执行RemoveExistingProducts得很早。所以我想我在这里应该是安全的。
此外,我试图运行heat.exe与-ag参数代替-gg。这会将所有组件的 Guid 更改为"*". 但这没有任何区别。
有一件事我做了升级日志的9003线的通知是这样的:MSI (s) (E4:1C) [17:12:46:123]: Skipping RemoveExistingProducts action: current configuration is maintenance mode or an uninstall。也许这表明一些潜在的问题。但是当我在升级过程中查看我的应用程序的实际 bin 文件夹时,我可以清楚地看到首先所有文件都被删除,然后我可以看到文件夹如何再次填充(但不是NLog.dll)。
所有这些都不能真正解释为什么升级适用于所有其他文件,但不适用于一个文件。此外,我已经使用类似的安装程序部署了我的产品的几个以前版本,我以前从未遇到过这个问题。
您正在尝试降级 NLog.dll 的版本。MSI 中存在一个错误,导致文件被删除而不是重新安装。唯一的解决方法是完全卸载然后重新安装。
解决这个问题的关键提示来自 Bob Arnson:
您正在尝试降级 NLog.dll 的版本。MSI 中存在错误,导致文件被删除且无法重新安装。
事实上,我的软件的最新版本引用了比我的软件的先前版本更旧的NLog.dll版本。
NLog.dll实际上是我的软件的间接依赖项。我引用NLog.Web.AspNetCore.dll,它又引用NLog.Extensions.Logging.dll和NLog.dll,所以我什至没有意识到NLog.dll的版本降级。
强迫客户卸载/重新安装不是一个选择。但我在这里找到了解决方案。
我创建了以下 XSL 转换,它从热输出中删除了三个单独的 NLog 组件,而是插入了一个包含所有三个文件的新组件,并且在我直接引用的文件上设置了 KeyPath:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns="http://schemas.microsoft.com/wix/2006/wi" exclude-result-prefixes="xsl wix">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<!-- Identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove individual components for NLog files and add the files in a single component, see CT-1886 -->
<!-- /sf/ask/3133599521/ -->
<xsl:key name="NLogFilesToRemove" match="wix:Component[contains(wix:File/@Source, 'NLog.dll') or contains(wix:File/@Source, 'NLog.Extensions.Logging.dll') or contains(wix:File/@Source, 'NLog.Web.AspNetCore.dll')]" use="@Id" />
<xsl:template match="*[self::wix:Component or self::wix:ComponentRef][key('NLogFilesToRemove', @Id)]" />
<xsl:template match="wix:ComponentGroup">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<Component Id="cmpBundledNLog" Directory="BinFolder" Guid="0d590e51-18bd-455a-9edf-c4ff34cce42e">
<File Id="fileNLogDll" KeyPath="no" Source="$(var.TempPublishDir)\NLog.dll" />
<File Id="fileNLogExtensionsLoggingDll" KeyPath="no" Source="$(var.TempPublishDir)\NLog.Extensions.Logging.dll" />
<File Id="fileNLogWebAspNetCoreDll" KeyPath="yes" Source="$(var.TempPublishDir)\NLog.Web.AspNetCore.dll" />
</Component>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
我不确定这将来会产生什么复杂性(在某些时候我想摆脱这个解决方法),但现在它似乎工作得很好。