Browse Source

Merge pull request #875 from mohe2015/fix-assembly-resolution

Don't crash if assembly resolution fails.
pull/876/merge
Daniel Grunwald 9 years ago committed by GitHub
parent
commit
9faeb9d680
  1. 145
      ICSharpCode.Decompiler.Console/CustomAssemblyResolver.cs
  2. 6
      ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

145
ICSharpCode.Decompiler.Console/CustomAssemblyResolver.cs

@ -5,78 +5,83 @@ using Mono.Cecil;
namespace ICSharpCode.Decompiler.Console namespace ICSharpCode.Decompiler.Console
{ {
class CustomAssemblyResolver : DefaultAssemblyResolver class CustomAssemblyResolver : DefaultAssemblyResolver
{ {
DotNetCorePathFinder dotNetCorePathFinder; DotNetCorePathFinder dotNetCorePathFinder;
readonly string assemblyFileName; readonly string assemblyFileName;
readonly Dictionary<string, UnresolvedAssemblyNameReference> loadedAssemblyReferences; readonly Dictionary<string, UnresolvedAssemblyNameReference> loadedAssemblyReferences;
public string TargetFramework { get; set; } public string TargetFramework { get; set; }
public CustomAssemblyResolver(string fileName) public CustomAssemblyResolver(string fileName)
{ {
this.assemblyFileName = fileName; this.assemblyFileName = fileName;
this.loadedAssemblyReferences = new Dictionary<string, UnresolvedAssemblyNameReference>(); this.loadedAssemblyReferences = new Dictionary<string, UnresolvedAssemblyNameReference>();
AddSearchDirectory(Path.GetDirectoryName(fileName)); AddSearchDirectory(Path.GetDirectoryName(fileName));
RemoveSearchDirectory("."); RemoveSearchDirectory(".");
} }
public override AssemblyDefinition Resolve(AssemblyNameReference name) public override AssemblyDefinition Resolve(AssemblyNameReference name)
{ {
var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None); var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None);
string file = null; string file = null;
switch (targetFramework[0]) { switch (targetFramework[0]) {
case ".NETCoreApp": case ".NETCoreApp":
case ".NETStandard": case ".NETStandard":
if (targetFramework.Length != 2) goto default; if (targetFramework.Length != 2) goto default;
if (dotNetCorePathFinder == null) { if (dotNetCorePathFinder == null) {
var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1]; var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1];
dotNetCorePathFinder = new DotNetCorePathFinder(assemblyFileName, TargetFramework, version, this.loadedAssemblyReferences); dotNetCorePathFinder = new DotNetCorePathFinder(assemblyFileName, TargetFramework, version, this.loadedAssemblyReferences);
} }
file = dotNetCorePathFinder.TryResolveDotNetCore(name); file = dotNetCorePathFinder.TryResolveDotNetCore(name);
if (file == null) { if (file == null) {
string dir = Path.GetDirectoryName(assemblyFileName); string dir = Path.GetDirectoryName(assemblyFileName);
if (File.Exists(Path.Combine(dir, name.Name + ".dll"))) if (File.Exists(Path.Combine(dir, name.Name + ".dll")))
file = Path.Combine(dir, name.Name + ".dll"); file = Path.Combine(dir, name.Name + ".dll");
else if (File.Exists(Path.Combine(dir, name.Name + ".exe"))) else if (File.Exists(Path.Combine(dir, name.Name + ".exe")))
file = Path.Combine(dir, name.Name + ".exe"); file = Path.Combine(dir, name.Name + ".exe");
} }
if (file == null) if (file == null)
return base.Resolve(name); return base.Resolve(name);
else else
return ModuleDefinition.ReadModule(file, new ReaderParameters() { AssemblyResolver = this }).Assembly; return ModuleDefinition.ReadModule(file, new ReaderParameters() { AssemblyResolver = this }).Assembly;
default: default:
return base.Resolve(name); return base.Resolve(name);
} }
} }
public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{ {
var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None); try {
string file = null; var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None);
switch (targetFramework[0]) { string file = null;
case ".NETCoreApp": switch (targetFramework[0]) {
case ".NETStandard": case ".NETCoreApp":
if (targetFramework.Length != 2) goto default; case ".NETStandard":
if (dotNetCorePathFinder == null) { if (targetFramework.Length != 2) goto default;
var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1]; if (dotNetCorePathFinder == null) {
dotNetCorePathFinder = new DotNetCorePathFinder(assemblyFileName, TargetFramework, version, this.loadedAssemblyReferences); var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1];
} dotNetCorePathFinder = new DotNetCorePathFinder(assemblyFileName, TargetFramework, version, this.loadedAssemblyReferences);
file = dotNetCorePathFinder.TryResolveDotNetCore(name); }
if (file == null) { file = dotNetCorePathFinder.TryResolveDotNetCore(name);
string dir = Path.GetDirectoryName(assemblyFileName); if (file == null) {
if (File.Exists(Path.Combine(dir, name.Name + ".dll"))) string dir = Path.GetDirectoryName(assemblyFileName);
file = Path.Combine(dir, name.Name + ".dll"); if (File.Exists(Path.Combine(dir, name.Name + ".dll")))
else if (File.Exists(Path.Combine(dir, name.Name + ".exe"))) file = Path.Combine(dir, name.Name + ".dll");
file = Path.Combine(dir, name.Name + ".exe"); else if (File.Exists(Path.Combine(dir, name.Name + ".exe")))
} file = Path.Combine(dir, name.Name + ".exe");
if (file == null) }
return base.Resolve(name, parameters); if (file == null)
else return base.Resolve(name, parameters);
return ModuleDefinition.ReadModule(file, parameters).Assembly; else
default: return ModuleDefinition.ReadModule(file, parameters).Assembly;
return base.Resolve(name, parameters); default:
} return base.Resolve(name, parameters);
} }
} } catch (AssemblyResolutionException exception) {
System.Console.WriteLine(exception.ToString());
return null;
}
}
}
} }

6
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -293,7 +293,7 @@ namespace ICSharpCode.Decompiler.CSharp
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, CancellationToken cancellationToken) IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, CancellationToken cancellationToken)
{ {
var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy( var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy(
delegate(TypeDefinition type) { delegate (TypeDefinition type) {
string file = CleanUpFileName(type.Name) + ".cs"; string file = CleanUpFileName(type.Name) + ".cs";
if (string.IsNullOrEmpty(type.Namespace)) { if (string.IsNullOrEmpty(type.Namespace)) {
return file; return file;
@ -301,7 +301,7 @@ namespace ICSharpCode.Decompiler.CSharp
string dir = CleanUpFileName(type.Namespace); string dir = CleanUpFileName(type.Namespace);
if (directories.Add(dir)) if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(targetDirectory, dir)); Directory.CreateDirectory(Path.Combine(targetDirectory, dir));
return Path.Combine(targetDirectory, dir, file); return Path.Combine(dir, file);
} }
}, StringComparer.OrdinalIgnoreCase).ToList(); }, StringComparer.OrdinalIgnoreCase).ToList();
DecompilerTypeSystem ts = new DecompilerTypeSystem(module); DecompilerTypeSystem ts = new DecompilerTypeSystem(module);
@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp
MaxDegreeOfParallelism = this.MaxDegreeOfParallelism, MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
CancellationToken = cancellationToken CancellationToken = cancellationToken
}, },
delegate(IGrouping<string, TypeDefinition> file) { delegate (IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) { using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) {
CSharpDecompiler decompiler = CreateDecompiler(ts); CSharpDecompiler decompiler = CreateDecompiler(ts);
decompiler.CancellationToken = cancellationToken; decompiler.CancellationToken = cancellationToken;

Loading…
Cancel
Save