Interesting fusion GAC install bug

A friend of mine was investigating a strange bug this past week that exposed an interesting bug in fusion (the piece of the .NET Framework that is used to manage the Global Assembly Cache aka the GAC). In this particular bug someone was trying to install the .NET Framework 1.1 on a Windows XP Media Center machine, and the .NET 1.1 setup ended up hanging.

The underlying reason for the hang was that this machine had a set of orphaned empty directories under %windir%\assembly\GAC (named like <assembly name>\<assembly version_strong name>) and the fusion code to install assemblies to the GAC had a bug where it would check for the existence of the directory that the file is expected to exist in within the GAC rather than checking that the file itself actually exists in that directory. For each of the assemblies that we tried to install as part of the .NET Framework 1.1 setup, there was an entry like this in the verbose MSI log:

MSI (s) (C8:D8): skipping installation of assembly component: {45B8FB98-2A6C-11D6-A551-0090278A1BB8} since the assembly already exists

Then when .NET Framework 1.1 setup tried to run ngen.exe at the end of setup to generate native images, it would hang because the underlying assembly actually was not present in the GAC (which in itself is another bug - it should gracefully fail with an informative error instead of hanging).

My friend and his team are still trying to figure out why the orphaned directories exist on the machine in the first place. It appears to be caused by performing an OS installation to a partition that previously had an OS installed to it without first performing a full format of that partition.

When my friend was telling me about this bug, it rang a bell for me from my past experience, so I dug through my email archive. I ended up finding a problem that I helped an internal customer solve that had the exact same symptoms and that exposed the same bug in fusion. So I wanted to go ahead and blog about this in case there are any setup developers or testers out there who are seeing odd behavior when trying to install assemblies to the GAC.