Last active
August 29, 2015 14:21
-
-
Save jdpilgrim/b7f2cf9d36241f57082f to your computer and use it in GitHub Desktop.
Does a recursive search of all references (dependant dlls). Invoking main with arg[0]=ROOT will search all deep dependancies of ROOT and print those in the same directory as ROOT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
public class MyTree<K, V> : Dictionary<K, MyTree<K, V>> | |
{ | |
public V Value { get; set; } | |
} | |
//http://www.pcreview.co.uk/forums/net-dependency-walker-t1227184.html | |
//http://stackoverflow.com/questions/1373100/how-to-add-folder-to-assembly-search-path-at-runtime-in-net | |
public class DependencyReporter | |
{ | |
private string _baseAssemblyName; | |
private AppDomain currentDomain = AppDomain.CurrentDomain; | |
private Assembly rootAssm; | |
public Assembly RootAssembly { get { return rootAssm; } } | |
public string RootAssemblyDirectory { get;set; } | |
private Dictionary<string, MyTree<AssemblyName, Assembly>> all = new Dictionary<string, MyTree<AssemblyName, Assembly>>(); | |
private MyTree<AssemblyName, Assembly> root = new MyTree<AssemblyName, Assembly>(); | |
public MyTree<AssemblyName, Assembly> Root { get { return root; } } | |
public DependencyReporter(string baseAssemblyName) | |
{ | |
_baseAssemblyName = baseAssemblyName; | |
currentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromSameFolder); | |
Hashtable alreadyLoaded = new Hashtable(); | |
rootAssm = Assembly.LoadFrom(baseAssemblyName); | |
RootAssemblyDirectory = Path.GetDirectoryName(rootAssm.Location); | |
PopulateDependencyTree(rootAssm, root); | |
} | |
void PopulateDependencyTree(Assembly assm, MyTree<AssemblyName, Assembly> references) | |
{ | |
AssemblyName fqn = assm.GetName(); | |
references.Value = assm; | |
foreach (AssemblyName name in assm.GetReferencedAssemblies()) | |
{ | |
MyTree<AssemblyName, Assembly> subTree; | |
if(!all.TryGetValue(name.FullName, out subTree)) | |
{ | |
subTree = new MyTree<AssemblyName, Assembly>(); | |
all.Add(name.FullName, subTree); | |
Assembly referenced = Assembly.Load(name); | |
PopulateDependencyTree(referenced, subTree); | |
references.Add(name, subTree); | |
} | |
else | |
{ | |
// empty to break loop | |
references.Add(name, new MyTree<AssemblyName, Assembly>() { Value = subTree.Value }); | |
} | |
} | |
} | |
private Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) | |
{ | |
Assembly from_same_dir = LoadFromPath(args, Path.GetDirectoryName(rootAssm.Location)); | |
return from_same_dir; | |
} | |
private Assembly LoadFromPath(ResolveEventArgs args, string folderPath) | |
{ | |
string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); | |
if (File.Exists(assemblyPath) == false) | |
{ | |
return null; | |
} | |
Assembly assembly = Assembly.LoadFrom(assemblyPath); | |
return assembly; | |
} | |
static void Main(string[] args) | |
{ | |
try | |
{ | |
string name; | |
if (args.Length == 0) | |
{ | |
Console.WriteLine("Usage: DependencyReporter <assembly1>"); | |
} | |
else | |
name = args[0]; | |
Console.WriteLine(name); | |
var depRep = new DependencyReporter(name); | |
//Print(depRep, depRep.Root, 0); | |
var dlls = depRep.Root | |
.Traverse(tree => tree.Value).Select(kvp => kvp.Value) | |
.Where(tree => Path.GetDirectoryName(tree.Value.Location) == depRep.RootAssemblyDirectory) | |
.Select(tree => Path.GetFileName(tree.Value.Location)) | |
.OrderBy(dir => dir) | |
.Distinct(); | |
foreach(string dll in dlls) | |
{ | |
Console.WriteLine(dll); | |
} | |
} | |
catch(Exception e) | |
{ | |
Console.WriteLine(e); | |
} | |
} | |
} | |
public static class Extensions { | |
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> items, | |
Func<T, IEnumerable<T>> childSelector) | |
{ | |
var stack = new Stack<T>(items); | |
while(stack.Any()) | |
{ | |
var next = stack.Pop(); | |
yield return next; | |
foreach(var child in childSelector(next)) | |
stack.Push(child); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment