Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 枚举程序集的所有已安装版本(在GAC中)_C#_Dll_X86_64 Bit_Gac - Fatal编程技术网

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

C# 枚举程序集的所有已安装版本(在GAC中),c#,dll,x86,64-bit,gac,C#,Dll,X86,64 Bit,Gac,是否可以使用C#枚举GAC中程序集的所有已安装版本?例如,我有一个名为“My.assembly”的程序集。该程序集可能有各种版本(“1.0.0.0”、“2.3.4.5”、“0.1.2.4”和……),并且可以针对各种平台(x86、x64、任何CPU)进行编译 现在我需要一种方法来确定安装了哪些版本/平台 我知道我可以列举GAC中的目录,但这似乎是错误的。应该有更好的方法来做到这一点 背景 我有一个启动程序应用程序,用户在其中选择一个DLL。启动器从DLL中检索一些信息(不加载),然后必须启动正确的

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

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

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

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

将a用于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);
    }
}

感谢汉斯·帕桑为我指明了正确的方向

您可以使用Fusion api、CreateSemblyEnum()和IAssemblyEnum+IAssemblyName执行此操作。这没有在.NET framework中公开,但它确实包含了它的代码。ILSpy或反射器会很方便的。@HansPassant引信似乎正是我要找的。但它似乎很难使用。如果有对这种事情的托管/内置支持,那就太好了。谢谢!旁注:如果fusion包装器是为Framework 2.0编译的,则它不会返回CLR版本4的全局程序集缓存中存在的结果。
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