寻找一个FOSS工具来显示.NET程序集链接依赖项

时间:2011-04-06 07:32:46

标签: .net dependencies .net-assembly

任何人都可以推荐一个可以分析.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();
    }
}
}

4 个答案:

答案 0 :(得分:2)

.NET Reflector 可以执行此操作,Microsoft的 ILDASM (我相信它包含在Windows SDK中)也是如此。

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

Example for .NET Reflector http://i56.tinypic.com/200el5c.png

在ILDASM中也是如此:

Example for ILDASM http://i56.tinypic.com/2qte1og.png

(Reflector最近已成为付费产品,但过去是免费的。请查看主页上的详细信息.ILDASM仍然可以自由使用,即使它可能不是你认为真正的FOSS。)

答案 1 :(得分:2)

自己创建这样的工具并不困难:

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

var refs = assembly.GetReferencedAssemblies();

refs将包含直接引用。

答案 2 :(得分:1)

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

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

enter image description here

答案 3 :(得分:0)

根据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();
    }
}
}