Browse Source

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

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

145
ICSharpCode.Decompiler.Console/CustomAssemblyResolver.cs

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

34
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp
{
#region Settings
DecompilerSettings settings = new DecompilerSettings();
public DecompilerSettings Settings {
get {
return settings;
@ -52,16 +52,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -52,16 +52,16 @@ namespace ICSharpCode.Decompiler.CSharp
settings = value;
}
}
/// <summary>
/// The MSBuild ProjectGuid to use for the new project.
/// <c>null</c> to automatically generate a new GUID.
/// </summary>
public Guid? ProjectGuid { get; set; }
public int MaxDegreeOfParallelism { get; set; } = Environment.ProcessorCount;
#endregion
// per-run members
HashSet<string> directories = new HashSet<string>(Platform.FileNameComparer);
@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// can access it.
/// </remarks>
protected string targetDirectory;
public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken))
{
string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(moduleDefinition.Assembly.Name.Name) + ".csproj");
@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.CSharp
DecompileProject(moduleDefinition, targetDirectory, writer, cancellationToken);
}
}
public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken))
{
if (string.IsNullOrEmpty(targetDirectory)) {
@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.CSharp
None,
Portable
}
#region WriteProjectFile
void WriteProjectFile(TextWriter writer, IEnumerable<Tuple<string, string>> files, ModuleDefinition module)
{
@ -248,7 +248,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -248,7 +248,7 @@ namespace ICSharpCode.Decompiler.CSharp
w.WriteEndDocument();
}
}
protected virtual bool IsGacAssembly(AssemblyNameReference r, AssemblyDefinition asm)
{
return false;
@ -272,7 +272,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -272,7 +272,7 @@ namespace ICSharpCode.Decompiler.CSharp
decompiler.AstTransforms.Add(new RemoveCLSCompliantAttribute());
return decompiler;
}
IEnumerable<Tuple<string, string>> WriteAssemblyInfo(DecompilerTypeSystem ts, CancellationToken cancellationToken)
{
var decompiler = CreateDecompiler(ts);
@ -293,7 +293,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -293,7 +293,7 @@ namespace ICSharpCode.Decompiler.CSharp
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, CancellationToken cancellationToken)
{
var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy(
delegate(TypeDefinition type) {
delegate (TypeDefinition type) {
string file = CleanUpFileName(type.Name) + ".cs";
if (string.IsNullOrEmpty(type.Namespace)) {
return file;
@ -301,7 +301,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -301,7 +301,7 @@ namespace ICSharpCode.Decompiler.CSharp
string dir = CleanUpFileName(type.Namespace);
if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(targetDirectory, dir));
return Path.Combine(targetDirectory, dir, file);
return Path.Combine(dir, file);
}
}, StringComparer.OrdinalIgnoreCase).ToList();
DecompilerTypeSystem ts = new DecompilerTypeSystem(module);
@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp
MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
CancellationToken = cancellationToken
},
delegate(IGrouping<string, TypeDefinition> file) {
delegate (IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) {
CSharpDecompiler decompiler = CreateDecompiler(ts);
decompiler.CancellationToken = cancellationToken;
@ -322,7 +322,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -322,7 +322,7 @@ namespace ICSharpCode.Decompiler.CSharp
return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken));
}
#endregion
#region WriteResourceFilesInProject
protected virtual IEnumerable<Tuple<string, string>> WriteResourceFilesInProject(ModuleDefinition module)
{
@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
}
protected virtual IEnumerable<Tuple<string, string>> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
{
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
@ -366,7 +366,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -366,7 +366,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
yield return Tuple.Create("EmbeddedResource", fileName);
}
string GetFileNameForResource(string fullName)
{
string[] splitName = fullName.Split('.');
@ -393,7 +393,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -393,7 +393,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
#endregion
/// <summary>
/// Cleans up a node name for use as a file name.
/// </summary>
@ -410,7 +410,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -410,7 +410,7 @@ namespace ICSharpCode.Decompiler.CSharp
text = text.Replace(c, '-');
return text;
}
public static string GetPlatformName(ModuleDefinition module)
{
switch (module.Architecture) {

Loading…
Cancel
Save