Find out dependencies of all DLLs?
C#.Net AssemblyAssembliesC# Problem Overview
I have a collection of DLLs(say 20). How do I find out all the DLLs on which one specific DLL (say DLL A) is depending upon?
C# Solutions
Solution 1 - C#
If you mean programmatically, use Assembly.GetReferencedAssemblies
.
You can use that recursively to find all the assemblies you need. (So you find the dependencies of X, then the dependencies of the dependencies, etc.)
Solution 2 - C#
Since the question is tagged "C#", I would assume you are talking about managed dlls (assemblies). In that case, dependencywalker is not useful. If you want to do that with a program, good ones are dotPeek by JetBrians and Reflector by RedGate. Or you can even use the object inspector in Visual Studio.
However, it can be a long process and cumbersome too. I would write a short C# program/F# script that uses Assembly.GetReferencedAssemblies
, as Jon mentioned.
If instead you want to examine native DLLs dependencies with a program (C# code), you have to walk the examine the PE file (the MS dll and exe file format) and its IAT (import address table). Not easy, but not impossible...
I would start here on MSDN and here to understand PE sections, and use a managed library to read it (there are many, including some from the Mono project (I'm thinking of Cecil, it should work with native binaries too); in the past I have used this one from the good John Gough.
Solution 3 - C#
You can use dependency walker http://www.dependencywalker.com to figure this out. Take note on the difference between x32 and x64 though.
> Dependency Walker is a free utility that scans any 32-bit or 64-bit > Windows module (exe, dll, ocx, sys, etc.) and builds a hierarchical > tree diagram of all dependent modules.
Solution 4 - C#
All answer credit goes to previous authors for the usage of Assembly.GetReferencedAssemblies
. This is just a write-and-forget C# console app that works solely for .NET assemblies. return 0
on assemblies you were able to check, and when successful, outputs them to STDOUT. Everything else will return 1
and print some kind of error output. You can grab the gist here.
using System;
using System.Reflection;
using System.IO;
namespace DotNetInspectorGadget
{
class DotNetInspectorGadget
{
static int Main(string[] args)
{
if(args.GetLength(0) < 1)
{
Console.WriteLine("Add a single parameter that is your" +
" path to the file you want inspected.");
return 1;
}
try {
var assemblies = Assembly.LoadFile(@args[0]).GetReferencedAssemblies();
if (assemblies.GetLength(0) > 0)
{
foreach (var assembly in assemblies)
{
Console.WriteLine(assembly);
}
return 0;
}
}
catch(Exception e) {
Console.WriteLine("An exception occurred: {0}", e.Message);
return 1;
} finally{}
return 1;
}
}
}
Usage:
call %cd%\dotnet_inspector_gadget.exe C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ConfigCI.Commands\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.ConfigCI.Commands.dll
Output:
> mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 > System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 > System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 > System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 > System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 > System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a > System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Solution 5 - C#
For .NET assemblies, a terrific tool to view the assemblies an assembly is dependent on is AsmSpy.
Solution 6 - C#
If you want the DLL's (the files) then, Assembly.GetReferencedAssemblies
will also return the .Net Framework assemblies.
Here is a simple code snippet that will get the dll's it can find in the current directory (and also include some other related files):
private readonly string[] _extensions = { ".dll", ".exe", ".pdb", ".dll.config", ".exe.config" };
private string[] GetDependentFiles(Assembly assembly)
{
AssemblyName[] asm = assembly.GetReferencedAssemblies();
List<string> paths = new List<string>(asm.Length);
for (int t = asm.Length - 1; t >= 0; t--)
{
for (int e = _extensions.Length - 1; e >= 0; e--)
{
string path = Path.GetFullPath(asm[t].Name + _extensions[e]);
if (File.Exists(path)) paths.Add(path);
}
}
return paths.ToArray();
}
You can call it like so: MessageBox.Show(string.Join("\r\n", GetDependentFiles(Assembly.GetEntryAssembly())));