How to programmatically determine if .NET assembly is installed in GAC?

前端 未结 2 1831
别跟我提以往
别跟我提以往 2020-12-30 05:57

What\'s the easiest way to check programmatically if an assembly is registered in the GAC (Global Assembly Cache) on the local machine? Is there some easy to use .NET API w

相关标签:
2条回答
  • 2020-12-30 05:59

    Check if CodeBase is null

    if (asm.CodeBase == null) {
         // IN GAC
    }
    
    0 讨论(0)
  • 2020-12-30 06:26

    This question is very similar to the following questions but mine is a little more precise, plus neither had an accepted answer and none of the answers offered seemed complete or optimal:

    • Check GAC for an assembly
    • Programmatically To check dll exists in Gac or not.If so display it in grid

    Originally I thought the following was the best approach but it doesn't work unless you specify the full name of the assembly and it's kind of hacky beacause of the try/catch but it's simple and works for many cases:

    public static class GacUtil
    {
        public static bool IsAssemblyInGAC(string assemblyFullName)
        {
            try
            {
                return Assembly.ReflectionOnlyLoad(assemblyFullName)
                               .GlobalAssemblyCache;
            }
            catch
            {
                return false;
            }
        }
    
        public static bool IsAssemblyInGAC(Assembly assembly)
        {
            return assembly.GlobalAssemblyCache;
        }
    }
    

    This is a better approach that works without a try/catch by using the Fusion API. It's a bunch more code but it works with partial assembly names:

    public static class GacUtil
    {
        [DllImport("fusion.dll")]
        private static extern IntPtr CreateAssemblyCache(
            out IAssemblyCache ppAsmCache, 
            int reserved);
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
        private interface IAssemblyCache
        {
            int Dummy1();
    
            [PreserveSig()]
            IntPtr QueryAssemblyInfo(
                int flags, 
                [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, 
                ref AssemblyInfo assemblyInfo);
    
            int Dummy2();
            int Dummy3();
            int Dummy4();
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct AssemblyInfo
        {
            public int cbAssemblyInfo;
            public int assemblyFlags;
            public long assemblySizeInKB;
    
            [MarshalAs(UnmanagedType.LPWStr)]
            public string currentAssemblyPath;
    
            public int cchBuf;
        }
    
        public static bool IsAssemblyInGAC(string assemblyName)
        {
            var assembyInfo = new AssemblyInfo { cchBuf = 512 };
            assembyInfo.currentAssemblyPath = new string('\0', assembyInfo.cchBuf);
    
            IAssemblyCache assemblyCache;
    
            var hr = CreateAssemblyCache(out assemblyCache, 0);
    
            if (hr == IntPtr.Zero)
            {
                hr = assemblyCache.QueryAssemblyInfo(
                    1, 
                    assemblyName, 
                    ref assembyInfo);
    
                if (hr != IntPtr.Zero)
                {
                    return false;
                }
    
                return true;
            }
    
            Marshal.ThrowExceptionForHR(hr.ToInt32());
            return false;
        }
    }
    
    0 讨论(0)
提交回复
热议问题