|
|
|
@ -1,6 +1,7 @@ |
|
|
|
using System; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.IO; |
|
|
|
using System.IO; |
|
|
|
|
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Text; |
|
|
|
using ICSharpCode.Decompiler.Util; |
|
|
|
using ICSharpCode.Decompiler.Util; |
|
|
|
using Mono.Cecil; |
|
|
|
using Mono.Cecil; |
|
|
|
@ -15,6 +16,7 @@ namespace ICSharpCode.Decompiler |
|
|
|
readonly string baseDirectory; |
|
|
|
readonly string baseDirectory; |
|
|
|
readonly List<string> directories = new List<string>(); |
|
|
|
readonly List<string> directories = new List<string>(); |
|
|
|
readonly List<string> gac_paths = GetGacPaths(); |
|
|
|
readonly List<string> gac_paths = GetGacPaths(); |
|
|
|
|
|
|
|
HashSet<string> targetFrameworkSearchPaths; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Detect whether we're in a Mono environment.
|
|
|
|
/// Detect whether we're in a Mono environment.
|
|
|
|
@ -46,7 +48,15 @@ namespace ICSharpCode.Decompiler |
|
|
|
return directories.ToArray(); |
|
|
|
return directories.ToArray(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string TargetFramework { get; set; } |
|
|
|
public string TargetFramework { |
|
|
|
|
|
|
|
get => targetFramework; |
|
|
|
|
|
|
|
set { |
|
|
|
|
|
|
|
if (targetFramework != value) { |
|
|
|
|
|
|
|
targetFramework = value; |
|
|
|
|
|
|
|
targetFrameworkSearchPaths = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError) |
|
|
|
protected UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -96,7 +106,7 @@ namespace ICSharpCode.Decompiler |
|
|
|
case ".NETCoreApp": |
|
|
|
case ".NETCoreApp": |
|
|
|
case ".NETStandard": |
|
|
|
case ".NETStandard": |
|
|
|
if (targetFramework.Length != 2) |
|
|
|
if (targetFramework.Length != 2) |
|
|
|
return ResolveInternal(name); |
|
|
|
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(mainAssemblyFileName, TargetFramework, version); |
|
|
|
dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, TargetFramework, version); |
|
|
|
@ -104,12 +114,56 @@ namespace ICSharpCode.Decompiler |
|
|
|
file = dotNetCorePathFinder.TryResolveDotNetCore(name); |
|
|
|
file = dotNetCorePathFinder.TryResolveDotNetCore(name); |
|
|
|
if (file != null) |
|
|
|
if (file != null) |
|
|
|
return file; |
|
|
|
return file; |
|
|
|
return ResolveInternal(name); |
|
|
|
goto default; |
|
|
|
|
|
|
|
case "Silverlight": |
|
|
|
|
|
|
|
if (targetFramework.Length != 2) |
|
|
|
|
|
|
|
goto default; |
|
|
|
|
|
|
|
file = ResolveSilverlight(name, new Version(targetFramework[1])); |
|
|
|
|
|
|
|
if (file != null) |
|
|
|
|
|
|
|
return file; |
|
|
|
|
|
|
|
goto default; |
|
|
|
default: |
|
|
|
default: |
|
|
|
return ResolveInternal(name); |
|
|
|
return ResolveInternal(name); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AddTargetFrameworkSearchPathIfExists(string path) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (targetFrameworkSearchPaths == null) { |
|
|
|
|
|
|
|
targetFrameworkSearchPaths = new HashSet<string>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (Directory.Exists(path)) |
|
|
|
|
|
|
|
targetFrameworkSearchPaths.Add(path); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// This only works on Windows
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
string ResolveSilverlight(AssemblyNameReference name, Version version) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddTargetFrameworkSearchPathIfExists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Microsoft Silverlight")); |
|
|
|
|
|
|
|
AddTargetFrameworkSearchPathIfExists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Silverlight")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var baseDirectory in targetFrameworkSearchPaths) { |
|
|
|
|
|
|
|
var versionDirectory = Path.Combine(baseDirectory, FindClosestVersionDirectory(baseDirectory, version)); |
|
|
|
|
|
|
|
var file = SearchDirectory(name, versionDirectory); |
|
|
|
|
|
|
|
if (file != null) |
|
|
|
|
|
|
|
return file; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string FindClosestVersionDirectory(string basePath, Version version) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string path = null; |
|
|
|
|
|
|
|
foreach (var folder in new DirectoryInfo(basePath).GetDirectories().Select(d => DotNetCorePathFinder.ConvertToVersion(d.Name)) |
|
|
|
|
|
|
|
.Where(v => v.Item1 != null).OrderByDescending(v => v.Item1)) { |
|
|
|
|
|
|
|
if (path == null || folder.Item1 >= version) |
|
|
|
|
|
|
|
path = folder.Item2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return path ?? version.ToString(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string ResolveInternal(AssemblyNameReference name) |
|
|
|
string ResolveInternal(AssemblyNameReference name) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (name == null) |
|
|
|
if (name == null) |
|
|
|
@ -159,29 +213,38 @@ namespace ICSharpCode.Decompiler |
|
|
|
#region .NET / mono GAC handling
|
|
|
|
#region .NET / mono GAC handling
|
|
|
|
string SearchDirectory(AssemblyNameReference name, IEnumerable<string> directories) |
|
|
|
string SearchDirectory(AssemblyNameReference name, IEnumerable<string> directories) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" }; |
|
|
|
|
|
|
|
foreach (var directory in directories) { |
|
|
|
foreach (var directory in directories) { |
|
|
|
foreach (var extension in extensions) { |
|
|
|
string file = SearchDirectory(name, directory); |
|
|
|
string file = Path.Combine(directory, name.Name + extension); |
|
|
|
if (file != null) |
|
|
|
if (!File.Exists(file)) |
|
|
|
return file; |
|
|
|
continue; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
return file; |
|
|
|
|
|
|
|
} catch (System.BadImageFormatException) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string SearchDirectory(AssemblyNameReference name, string directory) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" }; |
|
|
|
|
|
|
|
foreach (var extension in extensions) { |
|
|
|
|
|
|
|
string file = Path.Combine(directory, name.Name + extension); |
|
|
|
|
|
|
|
if (!File.Exists(file)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
return file; |
|
|
|
|
|
|
|
} catch (BadImageFormatException) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool IsZero(Version version) |
|
|
|
static bool IsZero(Version version) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; |
|
|
|
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static Version ZeroVersion = new Version(0, 0, 0, 0); |
|
|
|
static Version ZeroVersion = new Version(0, 0, 0, 0); |
|
|
|
|
|
|
|
private string targetFramework; |
|
|
|
|
|
|
|
|
|
|
|
string GetCorlib(AssemblyNameReference reference) |
|
|
|
string GetCorlib(AssemblyNameReference reference) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|