【问题标题】:Looking for a FOSS tool to display a .NET assemblies link dependencies [closed]寻找 FOSS 工具来显示 .NET 程序集链接依赖项 [关闭]
【发布时间】:2011-07-30 14:11:05
【问题描述】:

谁能推荐一个可以分析 .NET 程序集并列出其依赖项的工具(最好是 FOSS)?

我所追求的是一个工具,给定一个 .NET exe 文件可以生成一个报告,显示它链接到的 .NET 程序集(名称、版本、强名称、位置/GAC);为了在部署失败并且应用程序无法运行时帮助诊断。

当 fuse-log 查看器已经出错但有点笨拙时,它可以帮助执行此操作。我宁愿能够主动分析程序集并查看它在运行时需要什么,以便我可以验证它们是否存在。我查看了各种反射器工具,但这些列表类在所有链接的程序集中,并且没有它们的名称似乎表示强名称、版本等。

分辨率

感谢大家提供非常有用的反馈。虽然 ILDASM 免费提供了我需要的东西(我应该记住这一点),但当你想要的只是应用程序“x.exe”的依赖项时,它的使用并不是很优雅。

.NET Reflector 不再免费,NDepend 也不再免费(对于我的使用条款),因此必须拒绝这些。

所以我创建了可能是世界上最简单的控制台应用程序,它采用文件名并根据 Arve's 答案打印依赖项名称和版本,这足以满足我的需求。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace AssemblyDependencyViewer
{
class Program
{
    static void Main(string[] args)
    {
        if (File.Exists(args[0]))
        {
            DumpFileReferences(args[0]);
        }
        else
        {
            var dir = new DirectoryInfo(args[0]);
            if (dir.Exists)
            {
                var files = dir.GetFiles()
                    .Where((s) =>
                    {
                        return (s.Extension == ".exe") || (s.Extension == ".dll");
                    })
                    .OrderBy((s2) =>
                    {
                        return s2.Name;
                    })
                    ;

                foreach (var file in files)
                {
                    Console.WriteLine(string.Format("=== File {0} ====", file.FullName));
                    DumpFileReferences(file.FullName);
                }
            }
        }

        Console.ReadKey(false);
    }

    private static void DumpFileReferences(string fileName)
    {
        try
        {
            var assembly = Assembly.ReflectionOnlyLoadFrom(fileName);
            var refs = assembly.GetReferencedAssemblies();

            foreach (var x in refs.OrderBy((s) =>
            {
                return s.Name;
            }))
            {
                PrintFilename(x);
            }
        }
        catch (BadImageFormatException bif)
        {
            Console.WriteLine(bif.Message);
        }
        catch (FileLoadException fl)
        {
            Console.WriteLine(fl.Message);
        }
    }

    private static void PrintFilename(AssemblyName x)
    {
        if (x.Name.StartsWith("Apdcomms"))
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
        }
        Console.WriteLine(string.Format("{1,-10} {0}", x.Name, x.Version));
        Console.ResetColor();
    }
}
}

【问题讨论】:

  • +1,我也会对这样的工具感兴趣。但是:这样的工具是否只需要列出在程序集的元数据中引用的程序集,还是应该显示在代码中某处动态加载的程序集,即使用Assembly.Load?它应该递归地遵循程序集链接,还是只显示单个程序集的直接依赖关系?
  • 元数据应该足以满足我们当前的要求。
  • 您可能希望将问题中的答案变为实际答案。

标签: .net dependencies .net-assembly


【解决方案1】:

自己制作这样的工具并不难:

var assembly = Assembly.ReflectionOnlyLoadFrom(@"..the file...");

var refs = assembly.GetReferencedAssemblies();

refs 将包含直接引用。

【讨论】:

  • 感谢 Arve,我使用您的建议编写了一个简单的控制台应用程序(请参阅已编辑的问题)。这以一种足够简单的格式完成了我实际需要的一切,供我们的测试部门使用。
【解决方案2】:

.NET Reflector 可以做到这一点,微软的 ILDASM 也可以(我相信它包含在 Windows SDK 中)。

它们不仅显示程序集中的类,还显示引用的程序集。例如,在 Reflector 中,链接的程序集显示在 References 节点中:

或在 ILDASM 中相同:

Example for ILDASM http://tinypic.com/images/404.gif

(Reflector 最近成为了一种付费产品,但以前是免费的。请参阅他们主页上的详细信息。ILDASM 仍然可以免费使用,即使它可能不是您认为真正的 FOSS。)

【讨论】:

    【解决方案3】:

    在 NDepend 项目属性 > Code to Analyze panel 中,有一个应用程序程序集列表 + 一个使用的第三方和 .NET Fx 程序集列表,以及所有信息(版本、pdb 可用?、强签名?、大小, 最后修改日期时间, 带有版本的引用程序集, 完整路径...)。

    如果 NDepend 发现不一致(如版本引用不匹配),则会在列表中显示警告,但也会在 NDepend 分析时显示。

    【讨论】:

      【解决方案4】:

      根据 Artjom B 的建议,我将我的答案作为答案发布,而不仅仅是对原始查询的更新,以防万一这有任何帮助。

      我创建了可能是世界上最简单的控制台应用程序,它采用文件名并根据Arve's 答案打印依赖项名称和版本,这足以满足我的需求。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.IO;
      using System.Reflection;
      
      namespace AssemblyDependencyViewer
      {
      class Program
      {
          static void Main(string[] args)
          {
              if (File.Exists(args[0]))
              {
                  DumpFileReferences(args[0]);
              }
              else
              {
                  var dir = new DirectoryInfo(args[0]);
                  if (dir.Exists)
                  {
                      var files = dir.GetFiles()
                          .Where((s) =>
                          {
                              return (s.Extension == ".exe") || (s.Extension == ".dll");
                          })
                          .OrderBy((s2) =>
                          {
                              return s2.Name;
                          })
                          ;
      
                      foreach (var file in files)
                      {
                          Console.WriteLine(string.Format("=== File {0} ====", file.FullName));
                          DumpFileReferences(file.FullName);
                      }
                  }
              }
      
              Console.ReadKey(false);
          }
      
          private static void DumpFileReferences(string fileName)
          {
              try
              {
                  var assembly = Assembly.ReflectionOnlyLoadFrom(fileName);
                  var refs = assembly.GetReferencedAssemblies();
      
                  foreach (var x in refs.OrderBy((s) =>
                  {
                      return s.Name;
                  }))
                  {
                      PrintFilename(x);
                  }
              }
              catch (BadImageFormatException bif)
              {
                  Console.WriteLine(bif.Message);
              }
              catch (FileLoadException fl)
              {
                  Console.WriteLine(fl.Message);
              }
          }
      
          private static void PrintFilename(AssemblyName x)
          {
              if (x.Name.StartsWith("Apdcomms"))
              {
                  Console.ForegroundColor = ConsoleColor.Magenta;
              }
              Console.WriteLine(string.Format("{1,-10} {0}", x.Name, x.Version));
              Console.ResetColor();
          }
      }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-03-04
        • 2011-03-16
        • 1970-01-01
        • 2011-09-20
        • 2012-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-26
        相关资源
        最近更新 更多