Cmdlets/src/XpandPwsh.Cmdlets/ResolveAssemblyDependencies/Resolve-AssemblyDependencies.cs
using System;
using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; using System.Reflection; using System.Runtime.InteropServices; using JetBrains.Annotations; using XpandPwsh.CmdLets; namespace XpandPwsh.Cmdlets.ResolveAssemblyDependencies{ [Cmdlet(VerbsDiagnostic.Resolve, "AssemblyDependencies")] [CmdletBinding] [CmdLetTag()][PublicAPI] public class ResolveAssemblyDependencies : PSCmdlet{ [Parameter(Mandatory = true,Position = 0)] public string AssemblyFile{ get; set; } [Parameter(Position = 3)] public SwitchParameter SkipGAC{ get; set; } [Parameter(Position = 2)] public string[] Locations{ get; set; }=new string[0]; protected override void ProcessRecord(){ base.ProcessRecord(); var sources = Locations.Concat(new[]{Path.GetDirectoryName(AssemblyFile)}).ToArray(); Assembly ResolveEventHandler(object sender, ResolveEventArgs args){ var name = args.Name; var indexOf = name.IndexOf(",", StringComparison.Ordinal); if (indexOf > 0) name = args.Name.Substring(0, indexOf); foreach (var location in sources){ var path = $"{Path.Combine(location, name)}.dll"; if (File.Exists(path)) return Assembly.LoadFile(path); } return null; } AppDomain.CurrentDomain.AssemblyResolve += ResolveEventHandler; Resolve(); AppDomain.CurrentDomain.AssemblyResolve -= ResolveEventHandler; } private void Resolve(){ var references = new HashSet<string>(); var pending = new Queue<AssemblyName>(); var file = (Assembly)this.Invoke($"Mount-Assembly {AssemblyFile}").First().BaseObject; WriteObject(file); pending.Enqueue(file.GetName()); while (pending.Count > 0){ var assemblyName = pending.Dequeue(); var value = assemblyName.ToString(); if (references.Contains(value)){ continue; } references.Add(value); try{ var assembly = Assembly.Load(assemblyName); if (assembly != null){ WriteObject(assembly); foreach (var sub in assembly.GetReferencedAssemblies()){ pending.Enqueue(sub); } foreach (var type in assembly.GetTypes()){ foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)){ var customAttribute = (DllImportAttribute) Attribute.GetCustomAttribute(method, typeof(DllImportAttribute)); if (customAttribute != null && !references.Contains(customAttribute.Value)){ references.Add(customAttribute.Value); } } } } } catch (Exception ex){ WriteError(new ErrorRecord(ex, ex.GetHashCode().ToString(), ErrorCategory.InvalidOperation,assemblyName.ToString())); } } } } } |