5
votes

What does error "error LGHT0204 : ICE57: Component 'XXX' has both per-user data and a keypath that can be either per-user or per-machine" mean?
Is it possible to fix this error?
In any case Wix creates the msi file and it is possible to install the application. Is it the real error or just a warning? Can I ignore this error in case if it is a warning? Or something should be corrected?
This is wxs file for my Single Package Authoring installation:

<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
  <Product Name='Foobar 1.0' Id='GUID' UpgradeCode='GUID'
    Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Acme Ltd.'>

    <Package Id='*' Keywords='Installer' Description="Acme's Foobar 1.0 Installer"
      Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
      InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />

    <Property Id="ALLUSERS" Secure="yes" Value="2" />
    <Property Id="MSIINSTALLPERUSER" Secure="yes" Value="1" />
    <Property Id='ApplicationFolderName' Value="Acme" />
    <Property Id='WixAppFolder' Value="WixPerUserFolder" />

    <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
    <Property Id='DiskPrompt' Value="Acme's Foobar 1.0 Installation [1]" />

    <Directory Id='TARGETDIR' Name='SourceDir'>
      <Directory Id='ProgramFilesFolder' Name='PFiles'>
        <Directory Id='Acme' Name='Acme'>
          <Directory Id='INSTALLDIR' Name='Foobar 1.0'>
          </Directory>
        </Directory>
      </Directory>

      <Directory Id="ProgramMenuFolder" Name="Programs">
        <Directory Id="ProgramMenuDir" Name="Foobar 1.0">
          <Component Id="ProgramMenuDir" Guid="GUID">
            <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
            <RegistryValue Root='HKMU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
          </Component>
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id="INSTALLDIR">
       <Component Id='MainExecutable' Guid='GUID'>
          <File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1' Source='FoobarAppl10.exe' >
             <Shortcut Id="startmenuFoobar10" Directory="ProgramMenuDir" Name="Foobar 1.0" WorkingDirectory='INSTALLDIR' Icon="Foobar10.exe" IconIndex="0" />
          </File>
          <RegistryKey Root="HKMU" Key="Software\[Manufacturer]\[ProductName]">
             <RegistryValue Name="FoobarEXE" Value="1" KeyPath="yes" Type="integer" />
          </RegistryKey>
       </Component>
    </DirectoryRef>

    <Feature Id='Complete' Title='Foobar 1.0' Description='The complete package.'
      Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
      <Feature Id='MainProgram' Title='Program' Description='The main executable.' Level='1'>
        <ComponentRef Id='MainExecutable' />
        <ComponentRef Id='ProgramMenuDir' />
      </Feature>
    </Feature>

    <Icon Id="Foobar10.exe" SourceFile="FoobarAppl10.exe" />

  </Product>
</Wix>
2

2 Answers

3
votes

The intention of the ICE57 checks is to verify components are not mixing per-user and per-machine files and/or registry settings. However Rob Mensching's comment in http://sourceforge.net/p/wix/mailman/message/26687047/ indicates the ICE57 checks are not perfect:

IIRC, this is a bug in ICE57. The Windows Installer team didn't look at ALLUSERS property when evaluating these values... that was a long time ago though so my memory may have decayed a bit.

Your sample looks correct with respect to Single Package Authoring rules. The two main target directories are ProgramFilesFolder and ProgramMenuFolder, both of which are redirected appropriately for per-user installs. The registry key root is HKMU, which ends up as HKLM on per-machine installs and HKCU on per-user installs.

This looks like a bug in ICE57. Sadly we don't have access to the ICE57 source, so it is difficult to fix directly. There are a couple of options to work around the problem:

Option 1 - Suppress ICE57

Not ideal because it suppresses all four rules this group, not just the rule that is failing.

Option 2 - Use Advertised Shortcuts

Change your short-cut to advertised, and lose the associated registry key. The MainExecutable component simplifies to:

   <Component Id='MainExecutable' Guid='GUID'>
      <File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1'
            Source='FoobarAppl10.exe' KeyPath='yes'>
         <Shortcut Id="startmenuFoobar10" 
                   Directory="ProgramMenuDir" 
                   Name="Foobar 1.0" 
                   WorkingDirectory='INSTALLDIR' 
                   Icon="Foobar10.exe" 
                   IconIndex="0" 
                   Advertise='yes'/>
      </File>
   </Component>

The ICE57 checks seem to be more reliable with advertised short-cuts.

Note about ICE Checks

All of the ICE checks are stored in the file darice.cub. This is actually a Windows Installer database file that you can open with Orca. In a typical WIX installation this file can be found in: C:\Program Files (x86)\WiX Toolset vX.Y\bin. If you open darice.cub in Orca you can see the ICE checks as custom actions. Most refer to one or more binary DLLs embedded in the file. A few are implemented as VBS.

2
votes

This question has been asked dozens of times. Rather than post all the links, please search for ICE57 in SO and refer to the explanations and answers. For example this:

(WiX) Program files shortcut for per-machine install

and this:

How to fix ICE57.Per-User installation

Short answer: Ignore it if you always install per user and fix it if you install per system. It's a static test on the MSI file and can't know which context the install will eventually be, so it gives the warning anyway.