Как обновить «вторичный» исполняемый файл с помощью Wix? - PullRequest
0 голосов
/ 06 декабря 2010

У меня есть msi setup, написанная в Wix 3. Ничего особенного, пара исполняемых файлов + некоторые манипуляции с реестром.

У нас есть 2 исполняемых файла, основное приложение и приложение Watch Dog, которое всегда работает (запускается, как только пользовательрегистрируется).

Я выпустил новую версию нашего программного обеспечения, в wix мы указываем обновить без предварительной деинсталляции.Когда запускается новая версия msi, она обновляет основное приложение, но приложение сторожевого таймера не обновляется (даже если оно не запущено, так что это не проблема "в использовании")

Я вставил под мой файл wxs, надеюсь, вы сможетепомогите мне определить проблему.

Заранее большое спасибо,

Джек

Это файл wxs:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?include Properties.wxi?>
  <Product Id="$(var.ProductCode)" Name="$(var.Title)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
    <Package Description="$(var.ProductName)" Comments="$(var.ProductName)" InstallerVersion="200" Compressed="yes" />

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

    <Media Id="1" Cabinet="product.cab" EmbedCab="yes" CompressionLevel="high"/>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="ApplicationRootFolder" Name="$(var.ProductName)">
          <Component Id="MyAppComponent" Guid="6657828D-0D3F-43A6-A2CB-375BFBB8A412">
            <RemoveFolder Id="ApplicationRootFolder" On="uninstall" />
            <File Id="MyAppMain" Name="MyApp.exe" Source="..\Release\MyApp.exe"/>
            <File Id="FirstRunApp" Name="FirstRunApp.exe" Source="..\Release\FirstRunApp.exe"/>
            <File Id="MyAppWatchDog" Name="MyAppWatchDog.exe" Source="..\Release\MyAppWatchDog.exe"/>
            <!--File Id="CheckSniffer" Name="CheckSniffer.exe" Source="..\Release\CheckSniffer.exe"/-->
            <File Id="License" Name="License.rtf" Source="License.rtf"/>
          </Component>
        </Directory>
      </Directory>
      <Directory Id="DesktopFolder" >
        <Component Id="DesktopShortcuts" Guid="5567ED7E-03F8-4AB8-AFB5-F8074F4ED1B5">
          <RegistryValue Id="RegShortcutDesktop" Root="HKCU" Key="Software\$(var.ProductName)" Name="DesktopSC" Value="1" Type="integer" KeyPath="yes" />
          <Shortcut Id="DesktopShortcut" Name="$(var.ProductName)" Directory="DesktopFolder" Description="$(var.ProductName)" Target="[ApplicationRootFolder]$(var.Name).exe" Icon="Icon.exe" WorkingDirectory="ApplicationRootFolder" />
        </Component>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ProjectMenuFolder" Name="$(var.ProductName)">
          <Component Id="StartMenuShortcuts" Guid="5567ED7E-03F8-4AB8-AFB5-F8074F4ED1B4">
            <RegistryValue Root="HKCU" Key="Software\$(var.ProductName)" Type="string" Value="[ApplicationRootFolder]" Name="InstallPath"/>
            <RegistryValue Root="HKCU" Key="Software\Microsoft\Windows\CurrentVersion\Run" Type="string" Value="[#MyAppWatchDog]" Name="MyAppWatchdog"/>
            <RegistryValue Root="HKCU" Key="Software\$(var.ProductName)" Type="string" Value="" />
            <Shortcut Id="ProgramMenuShortcut" Name="$(var.ProductName)" Description="$(var.ProductName)" Target="[ApplicationRootFolder]$(var.Name).exe" Icon="Icon.exe" WorkingDirectory="ApplicationRootFolder" />
            <Shortcut Id="UninstallProduct" Name="Uninstall" Description="Uninstalls the $(var.ProductName)" Target="[System64Folder]msiexec.exe" Arguments="/x {$(var.ProductCode)}" />
            <RemoveFolder Id="ProgramMenuDir" On="uninstall" />
            <RemoveRegistryKey Root="HKCU" Key="Software\$(var.ProductName)" Action="removeOnUninstall"/>
          </Component>
        </Directory>
      </Directory>
    </Directory>
    <Feature Id="DefaultFeature" Title="$(var.Name)" Level="1">
      <ComponentRef Id="MyAppComponent" />
      <ComponentRef Id="StartMenuShortcuts" />
      <ComponentRef Id="DesktopShortcuts" />
    </Feature>

    <Property Id="SEARCHWINPCAP">
      <RegistrySearch Id="RegistrySearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinPcapInst" Name="VersionMajor" Type="raw"/>
    </Property>

    <Property Id="WIXUI_INSTALLDIR" Value="ApplicationRootFolder"/>
    <Property Id="PRODUCTNAME" Value="$(var.ProductName)"/>
    <!--Property Id="SNIFFER_CHECK_RESULT" Value="0"/-->
    <WixVariable Id="WixUIBannerBmp" Value="logo.JPG" />
    <WixVariable Id="WixUILicenseRtf" Value="License.rtf" />

    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch $(var.Title)" />
    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
    <Property Id="WixShellExecTarget" Value="[#MyAppMain]" />
    <CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />

    <CustomAction Id="SetLaunchWatchDogTarget" Property="WixShellExecTarget" Value="[#MyAppWatchDog]" />
    <CustomAction Id="LaunchWatchDog" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />

    <Binary Id="BinBrowseForFile" SourceFile="tools\WinPcap_4_1_2.exe"/>
    <CustomAction Id='LaunchWinPcapSetup' BinaryKey="BinBrowseForFile" ExeCommand="/Install" Execute="deferred" Impersonate="no"  Return="check"/>
    <CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.'/>

    <Property Id="CUSTOM_TITLE" Value="$(var.Title) Setup" />
    <CustomAction Id='SetRepearTitle' Property='CUSTOM_TITLE' Value='Repair $(var.Title)'/>
    <CustomAction Id='SetRemoveTitle' Property='CUSTOM_TITLE' Value='Remove $(var.Title)'/>

    <!--debug-->
    <Binary Id="BinCustomAction" SourceFile="bin\release\CustomActions.CA.dll"/>
    <!--Binary Id="BinCheckSniffer" SourceFile="..\Release\CheckSniffer.exe"/-->
    <Property Id="USER_GUID_PATH" Value="Software\Licenses"/>
    <Property Id="USER_GUID" />
    <Property Id="DUBUG_URL" Value="http://debug.myapp.com/service/"/>
    <Property Id="DUBUG_STATE" Value="STARTED" />
    <CustomAction Id='SendRequest' BinaryKey="BinCustomAction" DllEntry="SendRequest" Execute="immediate" Return="check" />
    <CustomAction Id='SendRequest_WinPcap_Start' BinaryKey="BinCustomAction" DllEntry="SendRequest" Execute="immediate" Return="check" />
    <CustomAction Id='SendRequest_WinPcap_Finish' BinaryKey="BinCustomAction" DllEntry="SendRequest" Execute="immediate" Return="check" />
    <CustomAction Id='LicenseAgreement_Next' Property='DUBUG_STATE' Value='LICENSE_AGREED' />
    <CustomAction Id='InstallDirDlg_Install' Property='DUBUG_STATE' Value='INSTALL' />
    <CustomAction Id='Exit_Finish' Property='DUBUG_STATE' Value='FINISH' />
    <CustomAction Id='WinPcap_Start' Property='DUBUG_STATE' Value='WINPCAP_STARTED' />
    <CustomAction Id='WinPcap_Finish' Property='DUBUG_STATE' Value='WINPCAP_FINISHED' />
    <CustomAction Id='Traffic_Failed' Property='DUBUG_STATE' Value='TRAFFIC_FAILED' />
    <CustomAction Id='Traffic_Uninstalled' Property='DUBUG_STATE' Value='UNINSTALLED' />
    <CustomAction Id='Shell_icacls' Directory='ApplicationRootFolder' ExeCommand='icacls FirstRunApp.exe /setintegritylevel Low' Return="ignore" Execute="commit" Impersonate="no"/>

    <InstallExecuteSequence>
      <Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
      <Custom Action="WinPcap_Start" Before="SendRequest_WinPcap_Start" ><![CDATA[SEARCHWINPCAP < "4" AND NOT Installed]]></Custom>
      <Custom Action="SendRequest_WinPcap_Start" Before="LaunchWinPcapSetup"><![CDATA[SEARCHWINPCAP < "4" AND NOT Installed]]></Custom>
      <Custom Action="LaunchWinPcapSetup" Before="InstallFiles"><![CDATA[SEARCHWINPCAP < "4" AND NOT Installed]]></Custom>
      <!-- disable currently Custom Action="CheckSniffer" Before="Shell_icacls">NOT Installed</Custom-->
      <Custom Action="Shell_icacls" Before="InstallFinalize"><![CDATA[VersionNT >= 600 AND NOT Installed]]></Custom>
      <!--Custom Action="Shell_RunWatchDog" After="InstallFinalize"><![CDATA[NOT Installed]]></Custom-->
      <RemoveExistingProducts After="InstallFinalize"></RemoveExistingProducts>
      <Custom Action="Traffic_Uninstalled" Before='SendRequest'>Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
      <Custom Action="SendRequest" After='InstallFinalize'>Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
    </InstallExecuteSequence>

    <UI />
    <UIRef Id="WixUI_Wizard" />

    <PropertyRef Id="NETFRAMEWORK35" />
    <Condition Message="This application requires .NET Framework 3.5 SP1.">Installed OR NETFRAMEWORK35</Condition>

    <Icon Id="Icon.exe" SourceFile="..\MyApp\Resources\icon_main.ico" />
  </Product>
</Wix>

Ответы [ 2 ]

0 голосов
/ 02 февраля 2011

Спасибо всем, кто пытается помочь.

@ Космин Пирву был тем, у кого был правильный ответ. Мы не обновляли версию сторожевого приложения, поэтому оно не устанавливалось.

Спасибо

0 голосов
/ 02 февраля 2011

Первое, что бросается в глаза из вашего кода Wix, это то, что вы отправляете все исполняемые файлы внутри одного компонента, но для этого компонента нет KeyPath. Это очень плохая идея! Это определенно приведет ко многим проблемам с обслуживанием, таким как проблема, с которой ваш watchdog.exe не обновляется.

Установщик Windows считает компонент самой маленькой установочной единицей. Кроме того, установщик Windows будет смотреть на KeyPath только для того, чтобы решить, существует ли компонент (или его необходимо обновить и т. Д.) Поскольку у «MyAppComponent» нет пути к ключу, WI по умолчанию будет использовать Directory в качестве вашего пути к ключу. Это означает, что во время обновления, если WI обнаружит ваш каталог, он будет предполагать, что компонент уже установлен, и не будет обновлять какие-либо файлы в компоненте.

Практическое правило, которое следует соблюдать, заключается в том, что любой файл .exe или .dll должен быть единственным файлом в компоненте, а также должен являться траекторией ключей для вашего компонента. Я зашел так далеко, что создал компонент для каждого отдельного файла в моих установках, что позволит избежать многих головных болей в будущем. Попробуйте заменить MyAppComponent следующими компонентами:

<Directory Id="ApplicationRootFolder" Name="$(var.ProductName)">
  <Component Id="MyApp.exe" Guid="INSERT_GUID_HERE">
    <File Id="MyApp.exe" Name="MyApp.exe" Source="..\Release\MyApp.exe" KeyPath="yes"/>
  </Component>
  <Component Id="FirstRunApp.exe" Guid="INSERT_GUID_HERE">
    <File Id="FirstRunApp.exe" Name="FirstRunApp.exe" Source="..\Release\FirstRunApp.exe" KeyPath="yes"/>
  </Component>
  <Component Id="MyAppWatchDog.exe" Guid="INSERT_GUID_HERE">
    <File Id="MyAppWatchDog.exe" Name="MyAppWatchDog.exe" Source="..\Release\MyAppWatchDog.exe" KeyPath="yes"/>
  </Component>
  <Component Id="CheckSniffer.exe" Guid="INSERT_GUID_HERE">
    <File Id="CheckSniffer.exe" Name="CheckSniffer.exe" Source="..\Release\CheckSniffer.exe" KeyPath="yes"/>
  </Component>
  <Component Id="License.rtf" Guid="INSERT_GUID_HERE">
    <File Id="License.rtf" Name="License.rtf" Source="License.rtf" KeyPath="yes"/>
  </Component>
</Directory>

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

...