找出所有 DLL 的依赖关系?
Posted
技术标签:
【中文标题】找出所有 DLL 的依赖关系?【英文标题】:Find out dependencies of all DLLs? 【发布时间】:2013-02-13 08:01:43 【问题描述】:我有一组 DLL(比如 20 个)。如何找出某个特定 DLL(比如 DLL A)所依赖的所有 DLL?
【问题讨论】:
【参考方案1】:如果您指的是编程方式,请使用Assembly.GetReferencedAssemblies
。
您可以递归地使用它来查找您需要的所有程序集。 (所以你找到X的依赖,然后是依赖的依赖等等)
【讨论】:
您需要包含“使用 System.Reflection;” @greenfeet:不一定——例如,您可以使用var assemblies = typeof(Foo).Assembly.GetReferencedAssemblies();
。通常,不值得添加答案中引用的所有类型使用的所有命名空间 - 特别是当存在指向相关类型的链接时。我假设读者足够了解 C# 语言,知道何时添加 using
指令。
@theoski:使用指令只是意味着你不必完全限定名称......我真的不明白你在问什么。
@kayleeFrye_onDeck:鉴于它已被接受并且没有提供其他信息,我认为假设它是关于 .NET 程序集是合理的。
我知道这可能是意图,@JonSkeet,但是当我遇到这个问题时,我正在寻找关于 DLL 的不太具体的内容,问题的描述,它的标签,以及缺乏提及程序集与通用 DLL 可能会引起混淆。我不是在质疑您对 OP 的回答的有效性。【参考方案2】:
由于问题被标记为“C#”,我假设您在谈论托管 dll(程序集)。在这种情况下,dependencywalker 没有用。如果你想用一个程序来做到这一点,JetBrians 的 dotPeek 和 RedGate 的 Reflector 是不错的选择。或者您甚至可以使用 Visual Studio 中的对象检查器。
但是,这可能是一个漫长的过程,也很麻烦。正如 Jon 所说,我会编写一个使用 Assembly.GetReferencedAssemblies
的简短 C# 程序/F# 脚本。
如果您想检查程序(C# 代码)的本地 DLL 依赖关系,则必须检查 PE 文件(MS dll 和 exe 文件格式)及其 IAT(导入地址表)。不容易,但也不是不可能……
我会开始 here on MSDN 和 here 来理解 PE 部分,并使用托管库来阅读它(有很多,包括 Mono 项目中的一些(我在想 Cecil,它应该可以工作也可以使用原生二进制文件);过去我使用过来自优秀的 John Gough 的 this one。
【讨论】:
【参考方案3】:您可以使用dependency walker http://www.dependencywalker.com 来解决这个问题。请注意 x32 和 x64 之间的区别。
Dependency Walker 是一个免费实用程序,可以扫描任何 32 位或 64 位 Windows 模块(exe、dll、ocx、sys 等)并构建分层 所有依赖模块的树形图。
【讨论】:
【参考方案4】:所有答案归功于以前的作者使用Assembly.GetReferencedAssemblies
。这只是一个只适用于 .NET 程序集的即写即忘 C# 控制台应用程序。 return 0
在您能够检查的程序集上,成功后将它们输出到 STDOUT。其他一切都会return 1
并打印某种错误输出。你可以抓住要点here。
using System;
using System.Reflection;
using System.IO;
namespace DotNetInspectorGadget
class DotNetInspectorGadget
static int Main(string[] args)
if(args.GetLength(0) < 1)
Console.WriteLine("Add a single parameter that is your" +
" path to the file you want inspected.");
return 1;
try
var assemblies = Assembly.LoadFile(@args[0]).GetReferencedAssemblies();
if (assemblies.GetLength(0) > 0)
foreach (var assembly in assemblies)
Console.WriteLine(assembly);
return 0;
catch(Exception e)
Console.WriteLine("An exception occurred: 0", e.Message);
return 1;
finally
return 1;
用法:
call %cd%\dotnet_inspector_gadget.exe C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ConfigCI.Commands\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.ConfigCI.Commands.dll
输出:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
【讨论】:
【参考方案5】:对于 .NET 程序集,查看程序集所依赖的程序集的绝佳工具是 AsmSpy。
【讨论】:
它没有列出间接程序集。【参考方案6】:如果您需要 DLL(文件),Assembly.GetReferencedAssemblies
也将返回 .Net Framework 程序集。
这是一个简单的代码 sn-p,它将获取它可以在当前目录中找到的 dll(还包括一些其他相关文件):
private readonly string[] _extensions = ".dll", ".exe", ".pdb", ".dll.config", ".exe.config" ;
private string[] GetDependentFiles(Assembly assembly)
AssemblyName[] asm = assembly.GetReferencedAssemblies();
List<string> paths = new List<string>(asm.Length);
for (int t = asm.Length - 1; t >= 0; t--)
for (int e = _extensions.Length - 1; e >= 0; e--)
string path = Path.GetFullPath(asm[t].Name + _extensions[e]);
if (File.Exists(path)) paths.Add(path);
return paths.ToArray();
你可以这样称呼它:MessageBox.Show(string.Join("\r\n", GetDependentFiles(Assembly.GetEntryAssembly())));
【讨论】:
以上是关于找出所有 DLL 的依赖关系?的主要内容,如果未能解决你的问题,请参考以下文章