Файл не копируется (только) во время обновления - PullRequest
0 голосов
/ 25 октября 2018

Обзор

Для новой версии моего продукта v1.9.0 я создал новый установщик MSI.Предыдущая версия приложения v1.7.0.

Удаление старой версии и установка новой версии работает нормально.

Но когда я пытаюсь обновить старую версию с v1.9.0установщик, отсутствует ровно один файл ( NLog.dll ).Все остальные файлы копируются просто отлично.

Я использую heat.exe для создания компонентов для всех зависимостей моего приложения.Так что NLog.dll обрабатывается точно так же, как и любой другой файл, но это единственный файл, который демонстрирует это странное поведение.

Фрагменты журнала для 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).

Фрагменты журнала для какого-либо другого файла из обновления до v1.9.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 не копируется.

Записывать фрагменты исходной установки v1.7.0

Я не знаю, имеет ли это какое-либо отношение, но здесьявляются связанными фрагментами журнала для этих двух файлов из первоначальной установки.Возможно, это имеет значение из-за идентификаторов, которые они имели во время первоначальной установки.

Строка 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>

Вещи, которые я рассмотрел

  • Очень похожий вопрос здесь .Кажется, важно выполнить RemoveExistingProducts как можно раньше.Если я правильно понимаю this , используя директиву 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 ).

Все это на самом деле не объясняет, почему обновление работает хорошо для всех остальных файлов, но не для одного.Также я развернул несколько предыдущих версий моего продукта с аналогичным установщиком, и у меня никогда не было этой проблемы раньше.

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Важный совет для решения этой проблемы пришел от Боба Арнсона:

Вы пытаетесь понизить версию 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 -->
  <!-- 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>

Я не уверен в сложностях, которые это создаст в будущем (в какой-то момент я бы хотел избавиться от этого обходного пути), но пока, похоже, работает нормально.

0 голосов
/ 01 августа 2019

Вы пытаетесь понизить версию NLog.Extensions.Logging.dll. Это не разрешено конфигурацией MSI по умолчанию, однако вы можете перезаписать ее, явно указав REINSTALLMODE вашего istaller.

Это может быть достигнуто путем перезаписи соответствующего свойства в разделе product вашего основного файла wix, чтобы обеспечить понижение

<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"/>
...
0 голосов
/ 26 октября 2018

Вы пытаетесь понизить версию NLog.dll.В MSI есть ошибка, из-за которой файл удаляется, а не переустанавливается.Единственный обходной путь - полностью удалить, а затем переустановить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...