static Assembly LoadAssembly(ref AssemblyInfo assemblyInfo, string loadPath) { string filePath = assemblyInfo.FilePath ?? Path.Combine(loadPath, assemblyInfo.AssemblyName.Name + ".dll"); try { assemblyInfo.IsInGac = true; return Assembly.ReflectionOnlyLoad(assemblyInfo.AssemblyName.FullName); } catch { assemblyInfo.IsInGac = false; } try { return Assembly.ReflectionOnlyLoadFrom(filePath); } catch (Exception ex) { // Possible unhandles exception: An attempt was made to load a program with an incorrect format. Console.WriteLine(ex); } return null; }
public static IEnumerable<AssemblyInfo> GetAssemblyReferenceGraph(string targetAssemblyPath) { string loadPath = Path.GetDirectoryName(targetAssemblyPath); var foundNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); // list of Assembly names to avoid dups and an endless loop var results = new List<AssemblyInfo>(); // ArrayList of AssemblyInfo objects var stack = new Stack<AssemblyInfo>(); // stack of Assembly AssemblyInfo objects stack.Push(new AssemblyInfo(AssemblyName.GetAssemblyName(targetAssemblyPath)) { FilePath = targetAssemblyPath }); // do a preorder, non-recursive traversal to store all remaining assemblies); while (stack.Count > 0) { var info = stack.Pop(); // get next assembly AssemblyInfo try { Assembly assembly = LoadAssembly(ref info, loadPath); if (assembly == null) continue; info.Children = assembly.GetReferencedAssemblies(); results.Add(info); foundNames.Add(info.FullName); foreach (var assemblyName in info.Children.Reverse()) // "right-to-left" = preorder traversal { if (!foundNames.Contains(assemblyName.FullName)) { foundNames.Add(assemblyName.FullName); var subChildInfo = new AssemblyInfo(assemblyName); stack.Push(subChildInfo); } } } catch (Exception e) { Console.WriteLine(e); } } return results; }