53

我有一组 DLL(比如 20 个)。如何找出某个特定 DLL(例如 DLL A)所依赖的所有 DLL?

4

6 回答 6

54

如果您的意思是以编程方式,请使用Assembly.GetReferencedAssemblies.

您可以递归地使用它来查找您需要的所有程序集。(所以你找到X的依赖关系,然后是依赖关系的依赖关系,等等)

于 2013-02-27T13:32:33.533 回答
16

由于问题被标记为“C#”,我假设您正在谈论托管 dll(程序集)。在这种情况下,dependencywalker 没有用。如果你想用一个程序来做到这一点,JetBrians 的 dotPeek 和 RedGate 的 Reflector 是不错的选择。或者您甚至可以使用 Visual Studio 中的对象检查器。

然而,这可能是一个漫长的过程,也很麻烦。Assembly.GetReferencedAssemblies正如 Jon 所提到的,我会编写一个简短的 C# 程序/F# 脚本,它使用.

相反,如果您想使用程序(C# 代码)检查本机 DLL 依赖关系,则必须检查 PE 文件(MS dll 和 exe 文件格式)及其 IAT(导入地址表)。不容易,但也不是不可能……

我将从MSDN这里开始了解 PE 部分,并使用托管库来阅读它(有很多,包括 Mono 项目中的一些(我在想Cecil,它也应该与本机二进制文件一起使用);在过去我用过好约翰·高夫的这个

于 2013-02-27T13:40:46.240 回答
11

您可以使用dependency walker http://www.dependencywalker.com来解决这个问题。请注意 x32 和 x64 之间的区别。

Dependency Walker 是一个免费实用程序,它可以扫描任何 32 位或 64 位 Windows 模块(exe、dll、ocx、sys 等)并构建所有依赖模块的层次树图。

于 2013-02-27T13:31:57.823 回答
10

所有答案都归功于以前的作者使用Assembly.GetReferencedAssemblies. 这只是一个只适用于 .NET 程序集的即写即忘 C# 控制台应用程序。return 0在您能够检查的程序集上,并在成功时将它们输出到 STDOUT。其他一切都会return 1打印出某种错误输出。你可以在这里抓住要点。

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
于 2017-04-27T23:45:05.147 回答
6

对于 .NET 程序集,查看程序集所依赖的程序集的绝佳工具是AsmSpy

于 2015-02-10T14:19:25.950 回答
1

如果您想要 DLL(文件),Assembly.GetReferencedAssemblies则还将返回 .Net Framework 程序集。

这是一个简单的代码片段,它将获取它可以在当前目录中找到的 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())));

于 2018-04-18T13:24:58.930 回答