是否可以使用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编译,暴露始终是相同的(平台无关的)接口。我使用LoadLibrary函数在C#应用程序中加载DLL。唯一的问题是该过程必须是匹配格式(x86或x64)。可以而且应该为x86,x64和任何CPU编译C#应用程序。
答案 0 :(得分:4)
使用managed wrapper Unmanaged 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指出我正确的方向!