enumerating assemblies in GAC

后端 未结 8 1858
故里飘歌
故里飘歌 2020-12-05 16:14

How can I enumerate all available assemblies in GAC in C#?

Actually I am facing an issue with a stupid code - the assembly called Telerik.Web.UI.dll is referred and

8条回答
  •  不知归路
    2020-12-05 16:43

    Check the way how fusion.dll is used in ILSpy to enumerate all the GAC assemblies.

    Fusion COM Wrappers

    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    
    namespace GacWithFusion
    {
        // .NET Fusion COM interfaces
        [ComImport, Guid("CD193BC0-B4BC-11D2-9833-00C04FC31D2E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAssemblyName
        {
            [PreserveSig]
            int SetProperty(uint PropertyId, IntPtr pvProperty, uint cbProperty);
    
            [PreserveSig]
            int GetProperty(uint PropertyId, IntPtr pvProperty, ref uint pcbProperty);
    
            [PreserveSig]
            int Finalize();
    
            [PreserveSig]
            int GetDisplayName([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder szDisplayName,
                               ref uint pccDisplayName,
                               uint dwDisplayFlags);
    
            [PreserveSig]
            int BindToObject(object refIID,
                             object pAsmBindSink,
                             IApplicationContext pApplicationContext,
                             [MarshalAs(UnmanagedType.LPWStr)] string szCodeBase,
                             long llFlags,
                             int pvReserved,
                             uint cbReserved,
                             out int ppv);
    
            [PreserveSig]
            int GetName(ref uint lpcwBuffer,
                        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwzName);
    
            [PreserveSig]
            int GetVersion(out uint pdwVersionHi, out uint pdwVersionLow);
    
            [PreserveSig]
            int IsEqual(IAssemblyName pName,
                        uint dwCmpFlags);
    
            [PreserveSig]
            int Clone(out IAssemblyName pName);
        }
    
        [ComImport(), Guid("7C23FF90-33AF-11D3-95DA-00A024A85B51"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IApplicationContext
        {
            void SetContextNameObject(IAssemblyName pName);
    
            void GetContextNameObject(out IAssemblyName ppName);
    
            void Set([MarshalAs(UnmanagedType.LPWStr)] string szName,
                     int pvValue,
                     uint cbValue,
                     uint dwFlags);
    
            void Get([MarshalAs(UnmanagedType.LPWStr)] string szName,
                     out int pvValue,
                     ref uint pcbValue,
                     uint dwFlags);
    
            void GetDynamicDirectory(out int wzDynamicDir,
                                     ref uint pdwSize);
        }
    
        [ComImport(), Guid("21B8916C-F28E-11D2-A473-00C04F8EF448"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAssemblyEnum
        {
            [PreserveSig]
            int GetNextAssembly(out IApplicationContext ppAppCtx,
                                out IAssemblyName ppName,
                                uint dwFlags);
    
            [PreserveSig]
            int Reset();
    
            [PreserveSig]
            int Clone(out IAssemblyEnum ppEnum);
        }
    
        internal static class Fusion
        {
            // dwFlags: 1 = Enumerate native image (NGEN) assemblies
            //          2 = Enumerate GAC assemblies
            //          4 = Enumerate Downloaded assemblies
            //
            [DllImport("fusion.dll", CharSet = CharSet.Auto)]
            internal static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum,
                                                          IApplicationContext pAppCtx,
                                                          IAssemblyName pName,
                                                          uint dwFlags,
                                                          int pvReserved);
        }
    }
    

    Main

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    
    namespace GacWithFusion
    {
        public class Program
        {
            static void Main(string[] args)
            {
                foreach (var assemblyName in GetGacAssemblyFullNames())
                {
                    Console.WriteLine(assemblyName.FullName);
                }
            }
    
            public static IEnumerable GetGacAssemblyFullNames()
            {
                IApplicationContext applicationContext;
                IAssemblyEnum assemblyEnum;
                IAssemblyName assemblyName;
    
                Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0);
                while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0)
                {
                    uint nChars = 0;
                    assemblyName.GetDisplayName(null, ref nChars, 0);
    
                    StringBuilder name = new StringBuilder((int)nChars);
                    assemblyName.GetDisplayName(name, ref nChars, 0);
    
                    AssemblyName a = null;
                    try
                    {
                        a = new AssemblyName(name.ToString());
                    }
                    catch (Exception)
                    {
                    }
    
                    if (a != null)
                    {
                        yield return a;
                    }
                }
            }
        }
    }
    

提交回复
热议问题