枚举程序集的所有已安装版本(在 GAC 中)

本文关键字:GAC 版本 安装 程序集 枚举 | 更新日期: 2023-09-27 18:37:14

是否可以使用 C# 枚举 GAC 中程序集的所有已安装版本?例如,我有一个名为"My.Assembly"的程序集。程序集可能有各种版本("1.0.0.0"、"2.3.4.5"、"0.1.2.4"等),并且可以针对各种平台(x86、x64、任何 CPU)进行编译。

现在我需要一种方法来确定安装了哪些版本/平台。

我知道我可以枚举 GAC 中的目录,但这似乎是错误的。应该有更好的方法来做到这一点。

背景我有一个启动器应用程序,用户在其中选择一个 DLL。启动器从 DLL 中检索一些信息(不加载它),然后必须启动处理 DLL 的正确托管 C# 应用程序。DLL 可以编译为 Win32 或 x64 放置公开始终相同的(与平台无关)接口。我使用 LoadLibrary 函数在 C# 应用程序中加载 DLL。唯一的问题是该过程必须具有匹配的格式(x86 或 x64)。C# 应用程序可以而且应该针对 x86、x64 和任何 CPU 进行编译。

枚举程序集的所有已安装版本(在 GAC 中)

使用非托管 Fusion API 的托管包装器 a 能够完全完成我想做的事情:

class Program
{
    static IEnumerable<AssemblyName> GetInstalledVersions(string name)
    {
        int result;
        IAssemblyName assemblyName;
        result = Utils.CreateAssemblyNameObject(out assemblyName, name, CreateAssemblyNameObjectFlags.CANOF_DEFAULT, IntPtr.Zero);
        if ((result != 0) || (assemblyName == null))
            throw new Exception("CreateAssemblyNameObject failed.");
        IAssemblyEnum enumerator;
        result = Utils.CreateAssemblyEnum(out enumerator, IntPtr.Zero, assemblyName, AssemblyCacheFlags.GAC, IntPtr.Zero);
        if ((result != 0) || (enumerator == null))
            throw new Exception("CreateAssemblyEnum failed.");
        while ((enumerator.GetNextAssembly(IntPtr.Zero, out assemblyName, 0) == 0) && (assemblyName != null))
        {
            StringBuilder displayName = new StringBuilder(1024);
            int displayNameLength = displayName.Capacity;
            assemblyName.GetDisplayName(displayName, ref displayNameLength, (int)AssemblyNameDisplayFlags.ALL);
            yield return new AssemblyName(displayName.ToString());
        }
    }
    static void Main(string[] args)
    {
        foreach (AssemblyName assemblyName in GetInstalledVersions("System.Data"))
            Console.WriteLine("{0} V{1}, {2}", 
                assemblyName.Name, assemblyName.Version.ToString(), assemblyName.ProcessorArchitecture);
    }
}

运行上面的程序给我以下输出:

System.Data V2.0.0.0, Amd64
System.Data V2.0.0.0, X86
System.Data V4.0.0.0, Amd64
System.Data V4.0.0.0, X86

感谢Hans Passant为我指明了正确的方向!