对于产品的新版本v1.9.0,我创建了一个新的MSI安装程序。该应用程序的先前版本是v1.7.0。
卸载旧版本,然后安装新版本可以正常工作。
但是,当我尝试使用v1.9.0安装程序更新旧版本时,恰好缺少一个文件( NLog.dll )。所有其他文件都可以复制。
我正在使用heat.exe为应用程序的所有依赖关系创建组件。因此, NLog.dll 的处理方式与其他文件完全相同,但这是唯一显示出这种奇怪行为的文件。
从升级到v1.9.0的这些是与此文件相关的日志片段。
第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).
第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:
第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).
为了进行比较,这是一些随机的其他文件( 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).
第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:
第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).
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
如您所见, 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).
第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).
第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
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
为了收集依赖性,我像这样运行 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"
生成的组件如下所示:
<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>
以及产品定义的相关部分:
<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>
有一个非常相似的问题here。重要的事情似乎是尽早执行RemoveExistingProducts
。如果我正确地理解了this,则使用MajorUpgrade
指令(我使用),默认情况下会非常早地执行RemoveExistingProducts
。所以我认为我应该在这里安全。
我还尝试使用-ag
参数而不是-gg
运行heat.exe。这会将所有组件的Guid更改为"*"
。但这没什么区别。
我在升级日志的第9003行上注意到的一件事是:MSI (s) (E4:1C) [17:12:46:123]: Skipping RemoveExistingProducts action: current configuration is maintenance mode or an uninstall
。也许这表明一些潜在的问题。但是,当我在升级过程中查看应用程序的实际bin文件夹时,可以清楚地看到首先删除所有文件,然后再看到如何再次填充该文件夹(但不是使用 NLog.dll < / em>)。
所有这些都不能真正解释为什么升级对所有其他文件都能正常进行,而对一个文件却不能正常进行的原因。另外,我已经使用类似的安装程序部署了该产品的多个先前版本,而我以前从未遇到过此问题。
答案 0 :(得分:2)
您正试图降级NLog.dll的版本。 MSI中存在一个错误,该错误导致文件被删除而不是重新安装。唯一的解决方法是完全卸载然后重新安装。
答案 1 :(得分:1)
解决这个问题的关键提示来自鲍勃·阿恩森:
您正试图降级NLog.dll的版本。 MSI中存在一个错误,该错误导致文件被删除而不是重新安装。
事实上,我软件的最新版本引用的是比以前软件版本更旧的 NLog.dll 版本。
NLog.dll 实际上是我的软件的间接依赖关系。我引用的是 NLog.Web.AspNetCore.dll ,而该引用又引用了 NLog.Extensions.Logging.dll 和 NLog.dll ,因此我甚至没有意识到版本 NLog.dll 的降级。
不能强迫客户卸载/重新安装。但是我找到了解决方法here。
我创建了以下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 -->
<!-- https://stackoverflow.com/questions/44765707/how-to-exclude-files-in-wix-toolset -->
<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>
我不确定将来会带来什么复杂性(有时我想摆脱这种变通方法),但目前看来还可以。
答案 2 :(得分:-1)
您正在尝试降级NLog.Extensions.Logging.dll MSI的默认配置不允许这样做,但是您可以通过明确指定istaller的REINSTALLMODE来覆盖它。
这可以通过覆盖主wix文件的product部分中的相应属性来实现降级来实现
<Product Id="*"
Name="MY SOFTWARE $(var.Version) $(var.Platform)"
Language="1033"
Version="$(var.Version)"
Manufacturer="The Umbrela Corporation"
UpgradeCode="someguid-guid-guid-guid-someguid">
...
<Property Id="REINSTALLMODE" Value="dmus"/>
...