diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 53b10fa6f..0f20b8c37 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -395,7 +395,7 @@ namespace ICSharpCode.Decompiler.CSharp settings.LoadInMemory = true; var file = LoadPEFile(fileName, settings); var resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors, - file.Reader.DetectTargetFrameworkId(), + file.DetectTargetFrameworkId(), settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default, settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None); return new DecompilerTypeSystem(file, resolver); diff --git a/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs b/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs index 22e847230..785841255 100644 --- a/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs @@ -296,7 +296,7 @@ namespace ICSharpCode.Decompiler.CSharp break; } - string targetFramework = module.Reader.DetectTargetFrameworkId(); + string targetFramework = module.DetectTargetFrameworkId(); if (!string.IsNullOrEmpty(targetFramework)) { string[] frameworkParts = targetFramework.Split(','); result.TargetFrameworkIdentifier = frameworkParts.FirstOrDefault(a => !a.StartsWith("Version=", StringComparison.OrdinalIgnoreCase) && !a.StartsWith("Profile=", StringComparison.OrdinalIgnoreCase)); diff --git a/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs b/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs index 0a3f17960..4b13e7b62 100644 --- a/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs +++ b/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs @@ -30,7 +30,13 @@ namespace ICSharpCode.Decompiler.Metadata { static readonly string RefPathPattern = @"(Reference Assemblies[/\\]Microsoft[/\\]Framework[/\\](?<1>.NETFramework)[/\\]v(?<2>[^/\\]+)[/\\])" + - @"|(NuGetFallbackFolder[/\\](?<1>[^/\\]+)\\(?<2>[^/\\]+)([/\\].*)?[/\\]ref[/\\])"; + @"|(NuGetFallbackFolder[/\\](?<1>[^/\\]+)\\(?<2>[^/\\]+)([/\\].*)?[/\\]ref[/\\])" + + @"|(shared[/\\](?<1>[^/\\]+)\\(?<2>[^/\\]+)([/\\].*)?[/\\])"; + + public static string DetectTargetFrameworkId(this PEFile assembly) + { + return DetectTargetFrameworkId(assembly.Reader, assembly.FileName); + } public static string DetectTargetFrameworkId(this PEReader assembly, string assemblyPath = null) { @@ -67,9 +73,9 @@ namespace ICSharpCode.Decompiler.Metadata if (type == ".NETFramework") { return $".NETFramework,Version=v{version}"; - } else if (type.Contains("netcore")) { + } else if (type.IndexOf("netcore", StringComparison.OrdinalIgnoreCase) >= 0) { return $".NETCoreApp,Version=v{version}"; - } else if (type.Contains("netstandard")) { + } else if (type.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0) { return $".NETStandard,Version=v{version}"; } } diff --git a/ILSpy/AssemblyList.cs b/ILSpy/AssemblyList.cs index c243bef9c..f98053a1d 100644 --- a/ILSpy/AssemblyList.cs +++ b/ILSpy/AssemblyList.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.ILSpy /// Dirty flag, used to mark modifications so that the list is saved later bool dirty; - internal readonly ConcurrentDictionary<(string assemblyName, bool isWinRT), LoadedAssembly> assemblyLookupCache = new ConcurrentDictionary<(string assemblyName, bool isWinRT), LoadedAssembly>(); + internal readonly ConcurrentDictionary<(string assemblyName, bool isWinRT, string targetFrameworkIdentifier), LoadedAssembly> assemblyLookupCache = new ConcurrentDictionary<(string assemblyName, bool isWinRT, string targetFrameworkIdentifier), LoadedAssembly>(); internal readonly ConcurrentDictionary moduleLookupCache = new ConcurrentDictionary(); /// diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index ff0947593..4ce66d2b5 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -65,7 +65,7 @@ namespace ICSharpCode.ILSpy public async Task GetTargetFrameworkIdAsync() { var assembly = await GetPEFileAsync().ConfigureAwait(false); - return assembly.Reader.DetectTargetFrameworkId() ?? string.Empty; + return assembly.DetectTargetFrameworkId() ?? string.Empty; } public ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo(); @@ -140,11 +140,15 @@ namespace ICSharpCode.ILSpy public string Text { get { if (IsLoaded && !HasLoadError) { - var metadata = GetPEFileOrNull()?.Metadata; + PEFile module = GetPEFileOrNull(); + var metadata = module?.Metadata; string versionOrInfo = null; if (metadata != null) { if (metadata.IsAssembly) { versionOrInfo = metadata.GetAssemblyDefinition().Version?.ToString(); + var tfId = GetTargetFrameworkIdAsync().Result; + if (!string.IsNullOrEmpty(tfId)) + versionOrInfo += ", " + tfId.Replace("Version=", " "); } else { versionOrInfo = ".netmodule"; } @@ -277,14 +281,15 @@ namespace ICSharpCode.ILSpy return debugInfoProvider; } - public LoadedAssembly LookupReferencedAssembly(Decompiler.Metadata.IAssemblyReference reference) + public LoadedAssembly LookupReferencedAssembly(IAssemblyReference reference) { if (reference == null) throw new ArgumentNullException(nameof(reference)); + var tfm = GetTargetFrameworkIdAsync().Result; if (reference.IsWindowsRuntime) { - return assemblyList.assemblyLookupCache.GetOrAdd((reference.Name, true), key => LookupReferencedAssemblyInternal(reference, true)); + return assemblyList.assemblyLookupCache.GetOrAdd((reference.Name, true, tfm), key => LookupReferencedAssemblyInternal(reference, true, tfm)); } else { - return assemblyList.assemblyLookupCache.GetOrAdd((reference.FullName, false), key => LookupReferencedAssemblyInternal(reference, false)); + return assemblyList.assemblyLookupCache.GetOrAdd((reference.FullName, false, tfm), key => LookupReferencedAssemblyInternal(reference, false, tfm)); } } @@ -308,19 +313,20 @@ namespace ICSharpCode.ILSpy static readonly Dictionary loadingAssemblies = new Dictionary(); MyUniversalResolver universalResolver; - LoadedAssembly LookupReferencedAssemblyInternal(Decompiler.Metadata.IAssemblyReference fullName, bool isWinRT) + LoadedAssembly LookupReferencedAssemblyInternal(IAssemblyReference fullName, bool isWinRT, string tfm) { - string GetName(Decompiler.Metadata.IAssemblyReference name) => isWinRT ? name.Name : name.FullName; + string key = tfm + ";" + (isWinRT ? fullName.Name : fullName.FullName); string file; LoadedAssembly asm; lock (loadingAssemblies) { foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) { - var reader = loaded.GetPEFileOrNull()?.Metadata; + var module = loaded.GetPEFileOrNull(); + var reader = module?.Metadata; if (reader == null || !reader.IsAssembly) continue; var asmDef = reader.GetAssemblyDefinition(); - var asmDefName = isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName(); - if (GetName(fullName).Equals(asmDefName, StringComparison.OrdinalIgnoreCase)) { + var asmDefName = loaded.GetTargetFrameworkIdAsync().Result + ";" + (isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName()); + if (key.Equals(asmDefName, StringComparison.OrdinalIgnoreCase)) { LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.FullName, MessageKind.Info, "Success - Found in Assembly List"); return loaded; }