Looking for a FOSS tool to display a .NET assembli

2019-07-15 11:04发布

问题:

Can anyone recommend a tool (ideally FOSS) that can analyse an .NET assembly and list its dependencies?

What I am after is a tool that given a .NET exe file can produce a report showing me the .NET assemblies (name, version, strong name, location/GAC) its is linked to; in order to assist diagnosis when a deployment fails and the application wont run.

The fuse-log viewer helps do this when its already gone wrong but its a bit clunky. I would rather be able to analyse the assembly pro-actively and see what it will need at runtime so I can validate they are present. I have looked at various reflector tools, but whist these list classes in all the linked assemblies, and names non of them seem to indicate strong names, versions etc.

Resolution

Thankyou all for the very useful feedback. Whilst ILDASM provides what I need for free (and I should have remembered that) its not very elegant in use when all you want is application "x.exe"'s dependancies.

.NET Reflector is not free anymore and neither is NDepend (for my usage terms) so those had to be rejected.

So I have created what is possibly the world's simplest console application which takes a filename and prints the dependancy names and verions based on Arve's answer which is quite suffient for my needs.

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:

It is not that difficult to create such a tool yourself:

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

var refs = assembly.GetReferencedAssemblies();

refs will then contain the direct references.



回答2:

.NET Reflector can do this, as can Microsoft's ILDASM (which is included in the Windows SDK, I believe).

They do not just show classes in an assembly, but also referenced assemblies. For example, in Reflector linked assemblies are shown in the References node:

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

Or the same in ILDASM:

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

(Reflector has recently become a paid-for product, but used to be free. See the details on their homepage. ILDASM can still be used freely, even if it's probably not what you'd consider truly FOSS.)



回答3:

In the NDepend Project Properties > Code to Analyze panel, there is a list of your application assemblies + a list of third-party and .NET Fx assemblies used, with all info (version, pdb available?, strong signed?, size, last modif datetime, referenced assemblies with versions, full path...).

If NDepend find inconsistency (like version referenced mistmatch), a warning is displayed in the list but also at NDepend analysis time.



回答4:

As per the suggestion by Artjom B I am posting my answer as an answer rather then just a update to the original query in case this is of any help.

I have created what is possibly the world's simplest console application which takes a filename and prints the dependancy names and verions based on Arve's answer which is quite suffient for my needs.

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