【问题标题】:Find out dependencies of all DLLs?找出所有 DLL 的依赖关系?
【发布时间】:2013-02-13 08:01:43
【问题描述】:

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

【问题讨论】:

    标签: c# .net-assembly assemblies


    【解决方案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 MSDNhere 来理解 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())));

          【讨论】:

            猜你喜欢
            • 2015-07-20
            • 2023-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多