Naming an assembly incorrectly when creating an MSI can cause a 1935 error with HRESULT 0x80131047

Recently, I heard from a customer who was attempting to create an MSI-based installer using WiX v3.0.  They needed to install an assembly to the global assembly cache (GAC) in their installer, but when they attempted to run their MSI, the installation failed.  The verbose MSI log file contained an error message like the following:

Error 1935. An error occurred during the installation of assembly 'MyAssembly,version="1.0.0.0",culture="neutral",publicKeyToken="################",processorArchitecture="MSIL"'. Please refer to Help and Support for more information. HRESULT: 0x80131047. assembly interface: IAssemblyCacheItem, function: Commit, component: {########-####-####-####-############}

From the information in corerror.h in the Windows SDK and in the blog post I wrote a while back about error code 1935, the HRESULT value 0x80131047 means "The given assembly name or code-base is invalid."

The customer tried installing the same assembly manually using gacutil.exe and it worked fine, so this error didn't make much sense initially.

After examining their WiX authoring and trying some scenarios, I discovered a tricky authoring error that ended up being the cause of this error.  The WiX authoring that led to the error looked like this:

<Component Id='MyComponent' Guid='PUT-GUID-HERE'>
    <File Id='MyFile'
            Name='MyName'
            DiskId='1'
            Source='MyAssembly.dll'
            Assembly='.net'
            KeyPath='yes' />
</Component>

The underlying issue turned out to be that the destination name of the file did not match the assembly identity for this assembly.  Behind the scenes, Windows Installer uses fusion APIs to install assemblies to the GAC, and fusion requires that the file name be the same as the assembly identity.  When the customer was attempting to manually run gacutil.exe on this assembly, they used the source file name (MyAssembly.dll in this case), which did match.  However, the WiX authoring caused the file to be installed with the name MyName, and then when Windows Installer attempted to call fusion APIs to install the assembly from the location the file was installed to, that copy of the file did not have a name that matched the assembly identity, and it resulted in a 1935 error with HRESULT 0x80131047.

Changing this setup authoring to the following and rebuilding the MSI allowed the installation to succeed:

<Component Id='MyComponent' Guid='PUT-GUID-HERE'>
    <File Id='MyFile'
            Name='MyAssembly.dll'
            DiskId='1'
            Source='MyAssembly.dll'
            Assembly='.net'
            KeyPath='yes' />
</Component>

Since this type of scenario is tricky to debug and it is also possible to catch it up-front when creating the MSI in the first place, I logged this bug on the WiX SourceForge site so that hopefully this will be caught in the WiX build process in the future.  In the meantime, if you are authoring assemblies to be installed to the GAC in WiX, make sure that the destination name being used for each of your assemblies matches the actual assembly identity.

Update: The WiX bug I logged has been fixed, and you will now receive a warning if you attempt to author an assembly in WiX v3.0 to install to the GAC but provide a destination file name that does not match the assembly identity.  That means that this scenario will no longer be reachable if you're using a recent build of WiX v3.0.

<update date="3/12/2009">Added a note indicating that the WiX bug I logged a while back has been fixed. </update>