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;
}
3条答案
按热度按时间oknwwptz1#
在加载插件之前,您可以仅为反射加载它,这将仅加载文件的元数据。例如:
请记住,关联的库可以具有它们的引用。
dba5bblo2#
您可以从文件元数据中提取这些信息。最快的方法可能是使用其中一个库来完成此操作。
例如,您可以使用Mono.Cecil
就像这样:
lyfkaqu13#
我也在努力解决这个问题,并想出了
Assembly.GetReferencedAssemblies()
。这将给予你一个程序集中所有被引用的程序集。然而,要在整个应用程序中获得它们,你需要做一个传递闭包来获得引用所引用的程序集,等等。这里有一个对我有用的函数。
以下是几个实用要点:您将看到我添加了一行代码来排除Microsoft和System程序集--如果您继续使用这个“兔子”程序集,您将得到大量的程序集。但是,您可以根据需要进行调整。此外,我还 Package 了程序集。由于我的经验是,有时您会得到一些无法加载或不再使用的dll,因此将其加载到try/catch块中。同样,您可以随意处理这些程序集。
很明显,你需要传入你正在使用的顶级程序集、主程序或其他任何东西。你可以使用如下代码轻松调用它:
其中
main
是最上层组件中的型别。