[英]How to get a programmatic list of all loaded assemblies (referenced) in the .NET Compact Framework
[英]How to get a list of all referenced assemblies (loaded or not)
我正在尝试获取我加载到 MEF 主应用程序中的程序集的引用程序集列表。
在运行插件之前,我想确保所有引用的程序集都存在于文件夹中。
我尝试使用
List<AssemblyName> a = Assembly.GetEntryAssembly().GetReferencedAssemblies().ToList();
但是当我这样做时,它只显示在那个阶段使用/加载的程序集。 我想要一个完整的列表(在运行时)引用的程序集(VS 中引用文件夹的副本),无论它们是在那个时候使用还是根本没有使用。
在加载插件之前,您可以加载它仅用于反射,只加载文件的元数据。 例如:
var assm = Assembly.ReflectionOnlyLoadFrom(@"Same.dll");
var reff = assm.GetReferencedAssemblies();
请记住,关联的库可以有他们的引用。
您可以从文件元数据中提取该信息。 最快的方法可能就是使用其中一个库来实现。
例如,您可以使用Mono.Cecil
像这样:
var md = ModuleDefinition.ReadModule(assemblyPath);
foreach (var reference in md.AssemblyReferences)
{
}
我也在为此苦苦挣扎,想出了Assembly.GetReferencedAssemblies()
。 这将为您提供程序集中所有引用的程序集。 但是,要在整个应用程序中获取它们,您需要执行传递闭包以获取引用等引用的程序集。
这是对我有用的 function。
private static List<Assembly> GetAllReferencedAssemblies(Assembly asm)
{
var nameQueue = new Queue<AssemblyName>(asm.GetReferencedAssemblies());
var alreadyProcessed = new HashSet<string>() { asm.FullName };
var result = new List<Assembly>();
result.Add(asm);
while (nameQueue.Any())
{
var name = nameQueue.Dequeue();
var fullName = name.FullName;
if (alreadyProcessed.Contains(fullName) || fullName.StartsWith("Microsoft.") || fullName.StartsWith("System."))
continue;
alreadyProcessed.Add(fullName);
try
{
var newAssembly = Assembly.Load(name);
result.Add(newAssembly);
foreach (var innerAsmName in newAssembly.GetReferencedAssemblies())
nameQueue.Enqueue(innerAsmName);
Debug.WriteLine(name);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
return result;
}
几个实用的要点:你会看到我添加了一行来排除 Microsoft 和系统程序集——如果你 go 整个兔子,你会得到大量的程序集。 但是,您可以根据需要进行调整。 此外,我将 Assembly.Load 包装在一个 try/catch 块中,因为我的经验是有时您会得到一些无法加载或不再使用的 dll。 再次强调,您可以随心所欲地使用它。
显然对你来说,你传递了你正在使用的顶级程序集,主程序或其他任何东西。 您可以使用以下内容轻松调用它:
var asmList = GetAllReferencedAssemblies(typeof(Main).Assembly);
其中main
是顶级程序集中的一种类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.