Register a dll into the GAC - but then it doesn't show up in the assembly window

I have this code to register dlls into my gac

 Assembly asm = Assembly.LoadFrom(argument);
    RegistrationServices regAsm = new RegistrationServices();
    bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);

and that works fine, i'm getting true to bResult, but when i open the GAC window i expected to see the dll there, but it is not. Can anyone explain me why?

When i drop the dll into the GAC window i see it there.


It is rather strange that this isn't wrapped by the .NET framework. The necessary fusion declarations are readily available. This code worked well:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

static class GacUtil {

    public static void InstallAssembly(string path, bool forceRefresh) {
        IAssemblyCache iac = null;
        CreateAssemblyCache(out iac, 0);
        try {
            uint flags = forceRefresh ? 2u : 1u;
            int hr = iac.InstallAssembly(flags, path, IntPtr.Zero);
            if (hr < 0) Marshal.ThrowExceptionForHR(hr);
        }
        finally {
            Marshal.FinalReleaseComObject(iac);
        }
    }

    public static void UninstallAssembly(string displayName) {
        IAssemblyCache iac = null;
        CreateAssemblyCache(out iac, 0);
        try {
            uint whatHappened;
            int hr = iac.UninstallAssembly(0, displayName, IntPtr.Zero, out whatHappened);
            if (hr < 0) Marshal.ThrowExceptionForHR(hr);
            switch (whatHappened) {
                case 2: throw new InvalidOperationException("Assembly still in use");
                case 5: throw new InvalidOperationException("Assembly still has install references");
                case 6: throw new System.IO.FileNotFoundException();    // Not actually raised
            }
        }
        finally {
            Marshal.FinalReleaseComObject(iac);
        }
    }


    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
    internal interface IAssemblyCache {
        [PreserveSig]
        int UninstallAssembly(uint flags, [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, IntPtr pvReserved, out uint pulDisposition);
        [PreserveSig]
        int QueryAssemblyInfo(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, IntPtr pAsmInfo);
        [PreserveSig]
        int CreateAssemblyCacheItem(/* arguments omitted */);
        [PreserveSig]
        int CreateAssemblyScavenger(out object ppAsmScavenger);
        [PreserveSig]
        int InstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath, IntPtr pvReserved);
    }

    [DllImport("mscorwks.dll", PreserveSig = false)]  // NOTE: use "clr.dll" in .NET 4+
    internal static extern void CreateAssemblyCache(out IAssemblyCache ppAsmCache, int reserved);
} 

Don't forget to press F5 in the Explorer window to refresh the view if you are adding and removing assemblies with this code.


Your code doesn't register the assembly in GAC, but, as explained here,

Registers the classes in a managed assembly to enable creation from COM.

which is not the same.


The method you are using is intended for COM registration. There is no official way of doing this.

Microsoft has a knowledgebase about how to use the undocumented GAC API

hope this helps,