[英]Enumerate all installed versions of an assembly (in GAC)
Is it possible to enumerate all installed versions of an assembly in GAC using C#? 是否可以使用C#枚举GAC中程序集的所有已安装版本? For example I have the assembly named "My.Assembly".
例如,我有一个名为“ My.Assembly”的程序集。 The assembly may come in various versions ("1.0.0.0", "2.3.4.5", "0.1.2.4", ...) and may be compiled for various platforms (x86, x64, Any CPU).
程序集可以有各种版本(“ 1.0.0.0”,“ 2.3.4.5”,“ 0.1.2.4”,...),并且可以针对各种平台(x86,x64,任何CPU)进行编译。
Now I need a way to determine which of the versions/platforms are installed. 现在,我需要一种方法来确定安装了哪个版本/平台。
I'm aware that I could enumerate the directories in GAC but that seems wrong. 我知道我可以枚举GAC中的目录,但这似乎是错误的。 There should be a better way to do this.
应该有一个更好的方法来做到这一点。
Background I have a launcher application in which the user selects a DLL. 背景我有一个启动器应用程序,用户可以在其中选择一个DLL。 The launcher retrieves some information from the DLL (without loading it) and then has to start the correct managed C# application which handles the DLL.
启动器从DLL中检索一些信息(不加载它),然后必须启动处理该DLL的正确的托管C#应用程序。 The DLL may be compiled for Win32 or x64 put exposes always the same (platform independent) interface.
可以为Win32或x64编译DLL,使其始终暴露相同的(独立于平台的)接口。 I use the LoadLibrary function to load the DLL in the C# applicaiton.
我使用LoadLibrary函数在C#应用程序中加载DLL。 The only problem is that the process has to be of matching format (x86 or x64).
唯一的问题是该进程必须具有匹配的格式(x86或x64)。 The C# application can and should be compiled for x86, x64 and Any CPU.
C#应用程序可以并且应该针对x86,x64和任何CPU进行编译。
Using a managed wrapper for the Unmanaged Fusion API a was able to do exactly what I wanted to do: 使用非托管Fusion API的托管包装程序 ,可以完全实现我想做的事情:
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);
}
}
Running the program above gives me the following output: 运行上面的程序给我以下输出:
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
Thanks to Hans Passant who pointed me in the right direction! 感谢Hans Passant指出了我正确的方向!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.