3

Using WIX, and trying to install two of the same assemblies, one for .Net35 and the other .Net40. I am using two separate components, however WIX is preventing the project from compiling.

        <Directory Id="GAC40" Name="GAC">
            <Component Id="MyDllServicesModuleGac40Component" Guid="307675AA-8AEC-473B-A78A-FB362CCEDE2A" Win64="yes">
                <File Id="MyDllNet40DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net40\MyDll.dll" />
            </Component>
        </Directory>
        <Directory Id="GAC35" Name="GAC">
            <Component Id="MyDllServicesModuleGac35Component" Guid="47E6BD1B-25CD-466D-945E-06DCF0F2A269" Win64="yes">
                <File Id="MyDllNet35DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net35\MyDll.dll" />
            </Component>
        </Directory>

The error I receive is:

Error 29 ICE30: The target file 'MyDll.dll' is installed in '[TARGETDIR]\GAC\' by two different components on an SFN system: 'MyDllServicesModuleGac40Component.DDD7D974_FE9C_4BA3_BDD3_A1A3A23F8057' and 'MyDllServicesModuleGac35Component.DDD7D974_FE9C_4BA3_BDD3_A1A3A23F8057'. This breaks component reference counting. D:\PROJECTS\MyDll.Experimental.3.0.0\Project\MyDll\MyDll.Wix.Services\MergeModule.wxs 34 1 MyDll.Wix.Services

The installer should be able to detect that the .Net35 dll gets installed to the GAC at C:\Windows\assembly, while the .Net40 dll gets installed to the GAC at C:\Windows\Microsoft.NET\assembly.

Renaming the DLLs is not an option.

Thanks!

UPDATE

Naturally I came up with a solution just after posting, seem wrapping the components in additional elements allowed me to get this to work. Later I read Tom Blodget's post so that is correct.

        <Directory Id="GAC1" Name="GAC">
            <Directory Id="GAC40" Name="GAC">
                <Component Id="MyDllServicesModuleGac40Component" Guid="307675AA-8AEC-473B-A78A-FB362CCEDE2A" Win64="yes">
                    <File Id="MyDllNet40DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net40\MyDll.dll" />
                </Component>
            </Directory>
        </Directory>
        <Directory Id="GAC2">
            <Directory Id="GAC35" Name="GAC">
                <Component Id="MyDllServicesModuleGac35Component" Guid="FD74504A-6FE9-488E-9086-9DAD3024B35D" Win64="yes">
                    <File Id="MyDllNet35DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net35\MyDll.dll" />
                </Component>
            </Directory>
        </Directory>

Well, hope it helps someone!

ISZ
  • 1,027
  • 2
  • 14
  • 29

1 Answers1

9

As explained by Aaron Stebner,

When you use the attribute Assembly=".net" for a file in WiX, it will create entries in the MsiAssembly and MsiAssemblyName table for this component and mark it as a GAC component. That means that the file will only be installed to the GAC by this component, and it will not install to the directory that the component is a child of. That directory will only be used by Windows Installer to stage a copy of that file when creating an administrative install point.

So the directories for your two components must be different since the file names are the same. If nothing else is targeted for those directories, they won't even be created. I put my GAC components under a subdirectory of my install folder:

<Directory Id="tmp_to_GAC" Name="tmp_to_GAC"> 

You'd need one for each GAC.

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72
  • Thanks, I hacked at it and came up with what you had described. – ISZ Jun 13 '13 at 18:42
  • 2
    Let me add a comment for newbies (as I am): The directory tag does not need to contain the string "GAC" in ID nor Name nor anything else. The only reason for files to be installed in GAC is the Assembly=".net" attribute. – Matteo TeoMan Mangano Feb 24 '17 at 13:08