116
votes

How do I determine the dependencies of a .NET application? Does Dependency Walker work with managed apps? I've downloaded the latest and tried profiling the app, but it just exits without much of an explanation. If it doesn't work with .NET, then is there some other tool that would help me debug a run-time DLL loading issue?

12

12 Answers

101
votes

Dependency walker works on normal win32 binaries. All .NET dll's and exe's have a small stub header part which makes them look like normal binaries, but all it basically says is "load the CLR" - so that's all that dependency walker will tell you.

To see which things your .NET app actually relies on, you can use the tremendously excellent .NET reflector from Red Gate. (EDIT: Note that .NET Reflector is now a paid product. ILSpy is free and open source and very similar.)

Load your DLL into it, right click, and chose 'Analyze' - you'll then see a "Depends On" item which will show you all the other dll's (and methods inside those dll's) that it needs.

It can sometimes get trickier though, in that your app depends on X dll, and X dll is present, but for whatever reason can't be loaded or located at runtime.

To troubleshoot those kinds of issues, Microsoft have an Assembly Binding Log Viewer which can show you what's going on at runtime

59
votes

I find the small utility AsmSpy an invaluable tool to for resolving issues with loading assemblies. It lists all assembly references of managed assemblies including assembly versions.

Run it in a command prompt in the directory of the .dll with the following arguments:

asmspy . all

asmspy output screenshot

Install it quickly with Chocolatey:

choco install asmspy
26
votes

Open the assembly file in ILDASM and look @ the .assembly extern in the MANIFEST

17
votes

You don't need to download and install shareware apps or tools. You can do it programitically from .NET using Assembly.GetReferencedAssemblies()

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

To browse .NET code dependencies, you can use the capabilities of the tool NDepend. The tool proposes:

For example such query can look like:

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 }

And its result looks like: (notice the code metric depth, 1 is for direct callers, 2 for callers of direct callers...) (notice also the Export to Graph button to export the query result to a Call Graph)

NDepend dependencies browsing through C# LINQ query

The dependency graph looks like:

NDepend Dependency Graph

The dependency matrix looks like:

NDepend Dependency Matrix

The dependency matrix is de-facto less intuitive than the graph, but it is more suited to browse complex sections of code like:

NDepend Matrix vs Graph

Disclaimer: I work for NDepend

6
votes

If you are using the Mono toolchain, you can use the monodis utility with the --assemblyref argument to list the dependencies of a .NET assembly. This will work on both .exe and .dll files.

Example usage:

monodis --assemblyref somefile.exe

Example output (.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

Example output (.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
4
votes

Enable assembly binding logging set the registry value EnableLog in HKLM\Software\Microsoft\Fusion to 1. Note that you have to restart your application (use iisreset) for the changes to have any effect.

Tip: Remember to turn off fusion logging when you are done since there is a performance penalty to have it turned on.

4
votes

It's funny I had a similar issue and didn't find anything suitable and was aware of good old Dependency Walker so in the end I wrote one myself.

This deals with .NET specifically and will show what references an assembly has (and missing) recursively. It'll also show native library dependencies.

It's free (for personal use) and available here for anyone interested: www.netdepends.com

www.netdepends.com

Feedback welcome.

1
votes

http://www.amberfish.net/

ChkAsm will show you all the dependencies of a particular assembly at once, including the versions, and easily let you search for assemblies in the list. Works much better for this purpose than ILSpy (http://ilspy.net/), which is what I used to use for this task.

0
votes

Another handy Reflector add-in that I use is the Dependency Structure Matrix. It's really great to see what classes use what. Plus it's free.

0
votes

Try compiling your .NET assembly with the option --staticlink:"Namespace.Assembly" . This forces the compiler to pull in all the dependencies at compile time. If it comes across a dependency that's not referenced it will give a warning or error message usually with the name of that assembly.

Namespace.Assembly is the assembly you suspect as having the dependency problem. Typically just statically linking this assembly will reference all dependencies transitively.

-5
votes

Best app that I see and use, show missed/problematic dlls: http://www.dependencywalker.com/