In addition to what JB Evain suggested, this code will help to avoid an exception. All you have to do is handle the exception in the resolver.
Not the best way, I admit. But it works for this scenario: "If I am decompiling a DLL on a system where the referred assemblies are not present, the decompilation fails (with exception.) At least, i would like to see the decompile code, for whatever has been resolved."
using System; using System.Collections.Generic; using Mono.Cecil; public class MyAssemblyResolver : BaseAssemblyResolver { private readonly IDictionary<string, AssemblyDefinition> cache; public MyAssemblyResolver() { this.cache = new Dictionary<string, AssemblyDefinition>(StringComparer.Ordinal); } public override AssemblyDefinition Resolve(AssemblyNameReference name) { if (name == null) throw new ArgumentNullException("name"); AssemblyDefinition assemblyDefinition = null; if (this.cache.TryGetValue(name.FullName, out assemblyDefinition)) return assemblyDefinition; try
And use it as follows:
var rp = new Mono.Cecil.ReaderParameters() { AssemblyResolver = new MyAssemblyResolver() }; var assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(assemblyStream, rp); var astBuilder = new ICSharpCode.Decompiler.Ast.AstBuilder( new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule)); astBuilder.AddAssembly(assemblyDefinition);
I would like to see an improvement in the decompiler: it currently ignores the ReaderParameters that the user sets in the DefaultAssemblyResolver class.
Using:
var rp = new Mono.Cecil.ReaderParameters(); var assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(assemblyStream, rp);
Current DefaultAssemblyResolver code:
public override AssemblyDefinition Resolve(AssemblyNameReference name) { if (name == null) { throw new ArgumentNullException("name"); } AssemblyDefinition assemblyDefinition; if (this.cache.TryGetValue(name.FullName, out assemblyDefinition)) { return assemblyDefinition; } assemblyDefinition = base.Resolve(name);
source share