0
votes

I am writing a Windows Installer package using the WiX Toolset. My application integrates with the Windows Forms WebBrowser control—basically Internet Explorer—and I need to ensure a minimum version of Internet Explorer in my installer. I did not find an easy, built-in method in WiX to check the Internet Explorer version (as there is with the .NET Framework), so I am following the WiX Tutorial's instructions for checking a file's version number during installation along with Microsoft's documentation of Internet Explorer version numbers (under the heading, How to determine the version of Internet Explorer for Windows, third bullet point).

Here is the relevant code from my Product.wxs file with explanatory comments included:

<Property Id="IE10ORHIGHER">
  <DirectorySearch Id="ProgFolder" Path="[ProgramFilesFolder]\Internet Explorer">
    <!-- I tried the following line to ensure that my DirectorySearch Path 
         and FileSearch Name attributes were functioning correctly.
         This line--without MinVersion set--results in the IE10ORHIGHER
         property being defined during installation, but it is useless
         because it merely detects that iexplore.exe exists rather than
         ensuring a minimum version.  -->
    <!-- <FileSearch Name="iexplore.exe" /> -->

    <!-- I need Internet Explorer 10 at minimum. -->
    <!-- IE10 RTM for Windows 8 version number: 10.0.9200.16384 -->
    <!-- IE10 RTM for Windows 7 version number: 10.0.9200.16521 -->
    <!-- Use IE10 RTM for Windows 8 version string. Minimum in FileSearch
         must be desired revision minus 1. See
         https://msdn.microsoft.com/library/aa371853.aspx -->
    <FileSearch Name="iexplore.exe" MinVersion="10.0.9200.16383" />
  </DirectorySearch>
</Property>

<!-- Requires Internet Explorer 10 or higher. -->
<Condition Message="This application requires Internet Explorer 10 or higher. Please upgrade Internet Explorer, and then run this installer again.">
  <![CDATA[Installed OR IE10ORHIGHER]]>
</Condition>

I am running Windows 8.1, and I have verified that the version of iexplore.exe on my system is 11.0.9600.17840. When I compile and run my installer with full logging (/l*vx) though, my condition message is displayed, and the software is not installed. Here is an excerpt from my MsiExec log file showing the search for the file, with stars inserted to point out important lines:

Action 22:10:12: AppSearch. Searching for installed applications
Action start 22:10:12: AppSearch.
★AppSearch: Property: IE10ORHIGHER, Signature: ProgFolder
AppSearch: Property: NETFRAMEWORK45, Signature: NetFramework45
MSI (c) (BC:54) [22:10:12:849]: PROPERTY CHANGE: Adding NETFRAMEWORK45 property. Its value is '#379893'.
Action ended 22:10:12: AppSearch. Return value 1.
MSI (c) (BC:54) [22:10:12:849]: Doing action: LaunchConditions
MSI (c) (BC:54) [22:10:12:849]: Note: 1: 2205 2:  3: ActionText 
Action 22:10:12: LaunchConditions. Evaluating launch conditions
Action start 22:10:12: LaunchConditions.
MSI (c) (BC:48) [22:10:12:856]: Font created.  Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
★This application requires Internet Explorer 10 or higher. Please upgrade Internet Explorer, and then run this installer again.
MSI (c) (BC:54) [22:10:14:276]: Note: 1: 2205 2:  3: Error 
MSI (c) (BC:54) [22:10:14:276]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1709 
★MSI (c) (BC:54) [22:10:14:276]: Product: MyProductName -- This application requires Internet Explorer 10 or higher. You have  installed. Please upgrade Internet Explorer, and then run this installer again.

Action ended 22:10:14: LaunchConditions. Return value 3.
Action ended 22:10:14: INSTALL. Return value 3.
Property(C): UpgradeCode = {MY-GUID-REMOVED}
Property(C): NETFRAMEWORK45 = #379893

For contrast, here is the log file from installation when I recompile with the FileSearch element's MinVersion attribute omitted. In this case, the iexplore.exe file is definitely found, the property is set, and the program installs fine (but of course, this is omitting the version check I need to accomplish!)

Action start 21:40:48: AppSearch.
AppSearch: Property: IE10ORHIGHER, Signature: ProgFolder
★MSI (c) (98:14) [21:40:48:761]: PROPERTY CHANGE: Adding IE10ORHIGHER property. Its value is 'C:\Program Files\Internet Explorer\iexplore.exe'.
AppSearch: Property: NETFRAMEWORK45, Signature: NetFramework45
MSI (c) (98:14) [21:40:48:762]: PROPERTY CHANGE: Adding NETFRAMEWORK45 property. Its value is '#379893'.
Action ended 21:40:48: AppSearch. Return value 1.
MSI (c) (98:14) [21:40:48:762]: Doing action: LaunchConditions
MSI (c) (98:14) [21:40:48:762]: Note: 1: 2205 2:  3: ActionText 
Action 21:40:48: LaunchConditions. Evaluating launch conditions
Action start 21:40:48: LaunchConditions.
Action ended 21:40:48: LaunchConditions. Return value 1.

★★★Numerous lines about the installation's progress skipped here★★★

Property(C): UpgradeCode = {MY-GUID-REMOVED}
★Property(C): IE10ORHIGHER = C:\Program Files\Internet Explorer\iexplore.exe
Property(C): NETFRAMEWORK45 = #379893

Why is my FileSearch failing to recognize that iexplore.exe's version of 11.0.9600.17840 is greater than the MinVersion attribute's value of 10.0.9200.16383?


Update with Problem Cause and Revised Question - 2015-08-25

In response to answers from Christopher Painter and Kiran Hegde, I began working on a minimal version of my installer project that would still show the error. In doing so, I found the problem: My installer is a dual-purpose package; by default, it runs per-user, and so my DirectorySearch element specifying Path="[ProgramFilesFolder]\Internet Explorer" was searching under %LOCALAPPDATA%\Programs rather than under %ProgramFiles%. I verified that this is the case by trying the following workarounds/tests at the command prompt, both of which allowed the installer to complete successfully:

Workaround/Test 1 - Copy IE to the place the installer is looking

robocopy "%ProgramFiles%\Internet Explorer" "%LOCALAPPDATA%\Programs\Internet Explorer" iexplore.exe
msiexec /package MyProductName.msi
rd /s /q "%LOCALAPPDATA%\Programs\Internet Explorer"

OR

Workaround/Test 2 - Specify per-machine installation

msiexec /package MyProductName.msi ALLUSERS=1

Finding the cause of the problem is great, but I still have a problem. My installer needs to run in either a per-user or per-computer context based on the user's choice. Since the MSI's ProgramFilesFolder variable is specific to the installation context, how can I test for IE's version under %ProgramFiles% when running in a per-user context?

2

2 Answers

1
votes

Can you try what you are trying to do in a test project and see if it works as expected? Because i tried your piece of code in a test project and it worked as expected. I used a windows 7 64 bit environment and the version of iexplore.exe on my system is 11.0.9600.17937.If i use 11.0.9600.17937 in the MinVersion field, i see the message(i.e the minimum required version which is 11.0.9600.17938 was not found. If i use 11.0.9600.17936 in the MinVersion field, i don't see the message (i.e the minimum required version 11.0.9600.17937 has been found) It shouldn't matter if its a windows 7 or a windows 8 environment as this behavior is dictated by the windows installer framework. BTW, what do you mean when you say that the version check is omitted? You will only see the launch condition firing if the required minimum version of Internet explorer is not found. As long as the logs indicate :LaunchConditions. Evaluating launch conditions, its safe enough to assume that the version check was being performed.

Here is my test project:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="FileSearch" Language="1033" Version="1.0.0.0" Manufacturer="Test" UpgradeCode="8790de3a-ca66-4577-b3cd-5a9df0ab15b2">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"  />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate EmbedCab="yes" />

        <Feature Id="ProductFeature" Title="FileSearch" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>

    <Property Id="IE10ORHIGHER">
  <DirectorySearch Id="ProgFolder" Path="[ProgramFilesFolder]\Internet Explorer">
    <!-- I tried the following line to ensure that my DirectorySearch Path 
         and FileSearch Name attributes were functioning correctly.
         This line without MinVersion set results in the IE10ORHIGHER
         property being defined during installation, but it is useless
         because it merely detects that iexplore.exe exists rather than
         ensuring a minimum version.  -->
    <!-- <FileSearch Name="iexplore.exe" /> -->

    <!-- I need Internet Explorer 10 at minimum. -->
    <!-- IE10 RTM for Windows 8 version number: 10.0.9200.16384 -->
    <!-- IE10 RTM for Windows 7 version number: 10.0.9200.16521 -->
    <!-- Use IE10 RTM for Windows 8 version string. Minimum in FileSearch
         must be desired revision minus 1. See
         https://msdn.microsoft.com/library/aa371853.aspx -->
    <FileSearch Name="iexplore.exe" MinVersion="11.0.9600.17936" />
  </DirectorySearch>
</Property>

<!-- Requires Internet Explorer 10 or higher. -->
<Condition Message="This application requires Internet Explorer 10 or higher. Please upgrade Internet Explorer, and then run this installer again.">
  <![CDATA[Installed OR IE10ORHIGHER]]>
</Condition>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="FileSearch" />
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">

             <Component Id="ProductComponent" Guid="{6CD6FBF0-8FE4-4882-80E1-DC16B9CED222}"> 
                <!-- TODO: Insert files, registry keys, and other resources here. -->
         <File Id="ProductFile" KeyPath="yes" Source="E:\Learning\Test Projects\Files\abc.dll" Name="abc.dll" />
            </Component> 
        </ComponentGroup>
    </Fragment>
</Wix>
1
votes

I can't repro your problem, it works for me. Are you doing this inside a merge module? If so, ProgramFilesFolder will be modularized and won't resolve to the directory you think it will unless you line that up.

Usually when it comes to the signature table (file search) the thing to know is that it takes language into consideration and isn't inclusive of the boundry if you don't specify it. See:

Signature Table

Note The language specified in the Languages column is used in the comparison and there is no way to ignore language. If you want a file to meet the MinVersion field requirement regardless of language, you must enter a value in the MinVersion field that is one less than the actual value. For example, if the minimum version for the filter is 2.0.2600.1183, use 2.0.2600.1182 to find the file without matching the language information.