0
votes

I have msi setup written in Wix 3. Nothing too fancy, couple executables + some registry manipulations.

We have 2 executables, the main application and watch dog application that is always running(it's started once user logs in).

I've released new version of our software, in wix we specify to upgrade without uninstalling first. When new version msi is ran, it upgrades main application but watchdog application is not upgraded(even if it's not running, so it's not "in-use" problem)

I pasted below my wxs file, hopefully you can help me spot the problem.

Thanks a lot in advance,

Jack

This is the wxs file:

<?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
What version of wix are you using? What operating system and service pack, and installed msi version does this behavior exist on? Does the upgrade work as expected when you explicitly close the watchdog application before running the upgrade? What does you wxs file look like?Rami A.
Wow, actually even if watchdog application is not running, it's not being overwritten, so I guess it's more fundamental. We're using Wix 3.Jack Juiceson
Does the watchdog application EXE have a higher version compared to the already installed file? Versioned files are updated only if the new package contains a higher version. If it does, try creating a log to see why the file is not overwritten.cosmin
Cosmin, thanks for raising that point. Actually watchdog is a new application we've added and didn't increment it's version. So now everything works! But I still have 1 question, on XP SP2 the behavior is different than on W7/Vista. In W7/Vista watchdog is closed by the installer but on XP it's not closed and user is prompted with reboot dialog. Only after reboot watchdog file gets replaced. Do you maybe know how to terminate a process in Wix in upgrade stage ? Thanks a lot againJack Juiceson

2 Answers

0
votes

The first thing that jumps at me from your Wix code is the fact that you are shipping all executables inside a single component but there is no KeyPath for the component. This is a very bad idea! It will definitely result in many servicing issues, such as the one you're experiencing with your watchdog.exe not updating.

Windows Installer considers a component the smallest installation unit. Furthermore, the Windows Installer will only look at the KeyPath to decide whether the component exists (or needs to be updated, etc.) Since the "MyAppComponent" has no keypath, the WI will default to using the Directory as your keypath. This means that during an upgrade, if WI finds your directory, it will assume the component is already installed and will not update any of the files in the component.

The rule of thumb to follow is that any .exe or .dll file must be the only file in the component, and it should also be the keypath for your component. I go as far as creating a component for each individual file in my setups, which will avoid many headaches in the future. Try replacing the MyAppComponent with these components instead:

<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>

This should resolve your updating issues. You may also want to conisder splitting your shortcut components into one shortcut per component, and setting an HKCU value as the keypath for each component.

0
votes

Thanks to everyone trying to help.

@Cosmin Pirvu was the one with correct answer. We didn't update the version of watchdog application and thus it was not being installed.

Thank you