【问题标题】:How do I determine the dependencies of a .NET application?如何确定 .NET 应用程序的依赖关系?
【发布时间】:2010-09-18 16:17:06
【问题描述】:

如何确定 .NET 应用程序的依赖关系? Dependency Walker 是否适用于托管应用程序?我已经下载了最新版本并尝试分析该应用程序,但它只是退出而没有太多解释。如果它不适用于 .NET,那么是否有其他工具可以帮助我调试运行时 DLL 加载问题?

【问题讨论】:

    标签: .net dll dependencies dependency-walker


    【解决方案1】:

    Dependency walker 适用于普通的 win32 二进制文件。所有 .NET dll 和 exe 都有一个小的 stub 标头部分,这使它们看起来像普通的二进制文件,但它基本上说的是“加载 CLR”——这就是依赖分析程序会告诉你的全部内容。

    要查看您的 .NET 应用程序实际依赖的东西,您可以使用 Red Gate 提供的非常出色的 .NET reflector。 (编辑:请注意,.NET Reflector 现在是付费产品。ILSpy 是免费和开源的,非常相似。)

    将您的 DLL 加载到其中,单击鼠标右键,然后选择“分析” - 然后您会看到一个“取决于”项,它将向您显示它需要的所有其他 dll(以及这些 dll 中的方法)。

    但有时它会变得更棘手,因为您的应用依赖于 X dll,并且存在 X dll,但由于某种原因无法在运行时加载或定位。

    为了解决这类问题,Microsoft 提供了一个Assembly Binding Log Viewer,它可以向您显示运行时发生的情况

    【讨论】:

    • 我想你错过了那个 URL - .aspx 被放在了链接文本中。不过我还是找到了。
    • 哦...是的,markdown 控件吃掉了 URL 中的括号,不幸的是 MSDN 将 (VS80) 放在了它的所有 url 中:-(
    • 请注意,从 2011 年初开始,.NET Reflector 不再免费。开源的 ILSpy 项目非常相似。
    • Assembly Binding Log View v4.0.30319.1 完全无法使用。日志条目不按时间顺序显示,您无法对其进行排序。它显示不适合查看器的路径,您无法调整其大小。这完全是浪费时间。
    • dependencywalker.com 你应该包括你提到的东西的网址,特别是。如果他们工作。
    【解决方案2】:

    启用程序集绑定日志将 HKLM\Software\Microsoft\Fusion 中的注册表值 EnableLog 设置为 1。请注意,您必须重新启动应用程序(使用 iisreset)才能使更改生效。

    提示:请记住在完成后关闭融合日志记录,因为打开它会降低性能。

    【讨论】:

      【解决方案3】:

      要浏览 .NET 代码依赖项,您可以使用工具 NDepend 的功能。该工具提出:

      例如,这样的查询可能如下所示:

      from m in Methods 
      let depth = m.DepthOfIsUsing("NHibernate.NHibernateUtil.Entity(Type)") 
      where depth  >= 0 && m.IsUsing("System.IDisposable")
      orderby depth
      select new { m, depth }
      

      它的结果看起来像:(注意代码度量 depth,1 用于直接调用者,2 用于直接调用者的调用者...)(另请注意导出到图形按钮以导出查询结果到Call Graph)

      依赖图如下:

      依赖矩阵如下:

      依赖矩阵事实上不如图表直观,但它更适合浏览复杂的代码部分,例如:

      免责声明:我为 NDepend 工作

      【讨论】:

      • Patrick 可能应该提到他是那个神奇工具的作者;)。真的值得一试。 +1 写它!
      • 嘿,我自己也注意到了这一点。我喜欢阅读他的博文——我得试试 NDepend!
      • @MitchWheat -- 姓名签出哈哈,“来自 NDepend 团队的帕特里克”
      • 我可以和 VStudio 一起使用吗?在非我的电脑上调试第三方应用程序崩溃
      【解决方案4】:

      我使用的另一个方便的反射器插件是Dependency Structure Matrix。看到什么类使用什么真是太好了。而且它是免费的。

      【讨论】:

      • 不显示版本号,不幸的是,至少作为 Visual Studio 插件安装的版本不显示。
      【解决方案5】:

      在 ILDASM 中打开程序集文件并查看 MANIFEST 中的 @.assembly extern

      【讨论】:

      • 我也可以这样查看依赖程序集的版本吗?我只看到依赖名称,而不是版本。
      • 实际上,是的,我也可以通过这种方式查看依赖程序集的版本,点击“M A N I F E S T”
      • 我更喜欢这个——如果你在开发环境中工作,不需要下载任何额外的实用程序
      • 调试第三方app崩溃时,如何只安装ildasm的客户?
      【解决方案6】:

      如果您使用 Mono 工具链,您可以使用 the monodis utility--assemblyref 参数来列出 .NET 程序集的依赖项。这将适用于 .exe.dll 文件。

      示例用法:

      monodis --assemblyref somefile.exe
      

      示例输出(.exe):

      $ monodis --assemblyref monop.exe
      AssemblyRef Table
      1: Version=4.0.0.0
          Name=System
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      2: Version=4.0.0.0
          Name=mscorlib
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      

      示例输出(.dll):

      $ monodis --assemblyref Mono.CSharp.dll
      AssemblyRef Table
      1: Version=4.0.0.0
          Name=mscorlib
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      2: Version=4.0.0.0
          Name=System.Core
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      3: Version=4.0.0.0
          Name=System
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      4: Version=4.0.0.0
          Name=System.Xml
          Flags=0x00000000
          Public Key:
      0x00000000: B7 7A 5C 56 19 34 E0 89
      

      【讨论】:

        【解决方案7】:

        http://www.amberfish.net/

        ChkAsm 将一次显示特定程序集的所有依赖项,包括版本,并让您轻松搜索列表中的程序集。 在此目的上比 ILSpy (http://ilspy.net/) 效果更好,这是我用来完成此任务的工具。

        【讨论】:

        • 截至 2019 年,该网站似乎是某种粗略的博客......
        • @McGuireV10 原来如此。那真不幸。并且快速谷歌搜索该应用程序没有任何点击。
        【解决方案8】:

        我看到和使用的最佳应用程序,显示丢失/有问题的 dll: http://www.dependencywalker.com/

        【讨论】:

        • 这个工具对 .NET 程序集没有帮助。
        【解决方案9】:

        您无需下载和安装共享软件应用程序或工具。您可以使用 Assembly.GetReferencedAssemblies() 以编程方式从 .NET 执行此操作

        Assembly.LoadFile(@"app").GetReferencedAssemblies()
        

        【讨论】:

        • 出于调试目的,通过 PowerShell 执行此操作更方便:[Reflection.Assembly]::LoadFile('C:\absolute\path\to\my.dll').GetReferencedAssemblies()。具有不为工具下载或寻找晦涩的 Windows 位置的好处。 +1
        • 如果我错了,请纠正我,但这只会给您带来与缺少依赖项的应用程序相同的错误,因此不是很有用
        • 这仅在程序集加载到 AppDomain 时有效。为反射加载的程序集返回一个空集。
        【解决方案10】:

        有趣的是,我遇到了类似的问题,但没有找到任何合适的东西,并且知道旧的 Dependency Walker,所以最后我自己写了一个。

        这专门处理 .NET,并将递归地显示程序集具有(和缺少)的引用。它还将显示本机库依赖项。

        它是免费的(供个人使用),任何感兴趣的人都可以在这里获得:www.netdepends.com

        欢迎反馈。

        【讨论】:

        • 请为打开程序集添加拖放支持。如果 XCOPY 部署以及源代码可用,那就太好了。
        • 我刚刚注意到网站没有任何明显的链接到有两个版本的部分,免费的一个用于非商业用途。通过在帮助菜单中找到“升级到专业”选项,我不小心偶然发现了这一点。下载页面上应该有一个通知说它不是免费用于商业用途的。
        • @gigaplex 我会记下这两个谢谢,我会看看我能做些什么。
        • Shiftclick 打开一棵树,所有子项也很有用。
        • 如何通知我缺少哪些依赖项?
        【解决方案11】:

        我发现小型实用程序AsmSpy 是解决加载程序集问题的宝贵工具。它列出了托管程序集的所有程序集引用,包括程序集版本。

        .dll 目录中的命令提示符下使用以下参数运行它:

        asmspy . all
        

        使用 Chocolatey 快速安装:

        choco install asmspy
        

        【讨论】:

        • 它也可以在 C# 文件或 Razor 视图上工作吗?我正在通过在运行时从 mvc 项目中导出一些视图和控制器来创建子项目。而且我想知道这些视图和控制器需要哪些依赖项,以便我可以在运行时复制这些依赖项,以使子项目可作为 IIS 上的单独 Web 项目发布。
        【解决方案12】:

        尝试使用选项 --staticlink:"Namespace.Assembly" 编译您的 .NET 程序集。这会强制编译器在编译时引入所有依赖项。如果遇到未引用的依赖项,它将给出警告或错误消息,通常带有该程序集的名称。

        Namespace.Assembly 是您怀疑存在依赖性问题的程序集。通常,仅静态链接此程序集将传递引用所有依赖项。

        【讨论】:

          【解决方案13】:

          为更新的 .Net 版本提供解决方案

          当 OP 提出问题时可能不是这种情况,但目前有一个内置的dotnet 命令用于列出解决方案中的包依赖项:

              PS C:\foo> dotnet list package
              Project 'foo' has the following package references
                  [net5.0]:
                  Top-level Package               Requested    Resolved
                  ...                             ...          ...
          

          更多信息可以在微软文档网站上找到:https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-list-package

          【讨论】:

            【解决方案14】:

            在我的公司,我们使用 Ashutosh Bhawasinka 的“装配信息”。它被实现为一个外壳扩展,因此您只需右键单击 *.dll 文件即可获得信息。您可以查看依赖关系树或获取所有依赖关系的平面列表。我喜欢这个工具的地方在于它还显示了公钥令牌,这是检查冲突的好方法。以下是我公司的一个程序集的平面列表输出示例:

            ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=484f84ea1d6cf4da
            mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089
            mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
            System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
            System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
            

            我们在 .Net Framework 4.0 中编译,因此您可以在 mscorlib 上看到该版本;我们还引用了为 .Net Framework 2.0 编译的 SharpZipLib,因此我们也看到了这种依赖关系。不错。

            唯一的问题是该实用程序发布在已关闭的 CodePlex 上。幸运的是,我们保留了原始文件的副本。我在网络上的其他任何地方都找不到它,所以我决定在这里发布它以供任何人获取(看起来我们只保存了 64 位版本):

            http://riosoftware.com/temp/pub/Assembly%20Information%20for%2064bit%20Operating%20System.zip

            如果您发现此链接和工具有用,请“支持”此答案以帮助他人!

            【讨论】:

              猜你喜欢
              • 2011-06-14
              • 1970-01-01
              • 2010-09-23
              • 1970-01-01
              • 2014-11-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-14
              相关资源
              最近更新 更多