Browse Source

Improve Framework Id detection (#3581)

* Support detecting .NET Core 1.0 and 1.1

* Formatting

* Fix version number

* Add support for using System.Private.CoreLib in version detection

* Move mscorlib for consistency and readability

* Ensure that netstandard is always checked before System.Runtime

* Ensure that System.Runtime is always checked before netstandard

* Formatting
pull/3604/head
Jeremy Pritts 2 months ago committed by GitHub
parent
commit
2f792f6fb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 81
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

81
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -79,6 +79,19 @@ namespace ICSharpCode.Decompiler.Metadata @@ -79,6 +79,19 @@ namespace ICSharpCode.Decompiler.Metadata
return $".NETFramework,Version=v{assemblyDefinition.Version.ToString(2)}";
case "netstandard":
return $".NETStandard,Version=v{assemblyDefinition.Version.ToString(2)}";
case "System.Runtime":
case "System.Private.CoreLib":
{
string version = GetDotNetCoreVersion(assemblyDefinition.Version);
if (version != null)
{
return $".NETCoreApp,Version=v{version}";
}
else
{
break;
}
}
}
}
@ -92,42 +105,20 @@ namespace ICSharpCode.Decompiler.Metadata @@ -92,42 +105,20 @@ namespace ICSharpCode.Decompiler.Metadata
string version;
switch (metadata.GetString(r.Name))
{
case "netstandard":
case "mscorlib":
version = r.Version.ToString(2);
return $".NETStandard,Version=v{version}";
return $".NETFramework,Version=v{version}";
case "System.Runtime":
// System.Runtime.dll uses the following scheme:
// 4.2.0 => .NET Core 2.0
// 4.2.1 => .NET Core 2.1 / 3.0
// 4.2.2 => .NET Core 3.1
// 5.0.0+ => .NET 5+
if (r.Version >= new Version(4, 2, 0))
case "System.Private.CoreLib":
version = GetDotNetCoreVersion(r.Version);
if (version != null)
{
if (r.Version.Major >= 5)
{
version = r.Version.ToString(2);
}
else if (r.Version.Major == 4 && r.Version.Minor == 2)
{
version = r.Version.Build switch {
<= 0 => "2.0",
1 => "3.0",
_ => "3.1"
};
}
else
{
version = "2.0";
}
return $".NETCoreApp,Version=v{version}";
}
else
{
continue;
}
case "mscorlib":
version = r.Version.ToString(2);
return $".NETFramework,Version=v{version}";
}
}
catch (BadImageFormatException)
@ -136,6 +127,24 @@ namespace ICSharpCode.Decompiler.Metadata @@ -136,6 +127,24 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
// We check for netstandard separately because .NET Core/Framework assemblies can reference it.
foreach (var h in metadata.AssemblyReferences)
{
try
{
var r = metadata.GetAssemblyReference(h);
if (r.PublicKeyOrToken.IsNil || metadata.GetString(r.Name) is not "netstandard")
continue;
string version = r.Version.ToString(2);
return $".NETStandard,Version=v{version}";
}
catch (BadImageFormatException)
{
// ignore malformed references
}
}
// Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)
if (assemblyPath != null)
{
@ -185,6 +194,24 @@ namespace ICSharpCode.Decompiler.Metadata @@ -185,6 +194,24 @@ namespace ICSharpCode.Decompiler.Metadata
return string.Empty;
}
static string GetDotNetCoreVersion(Version assemblyVersion)
{
// System.Runtime.dll and System.Private.CoreLib.dll use the following scheme:
// 4.1.0 => .NET Core 1.0 / 1.1
// 4.2.0 => .NET Core 2.0
// 4.2.1 => .NET Core 2.1 / 3.0
// 4.2.2 => .NET Core 3.1
// 5.0.0+ => .NET 5+
return (assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build) switch {
(4, 1, 0) => "1.1",
(4, 2, 0) => "2.0",
(4, 2, 1) => "3.0",
(4, 2, 2) => "3.1",
( >= 5, _, _) => assemblyVersion.ToString(2),
_ => null
};
}
public static bool IsReferenceAssembly(this MetadataFile assembly)
{
return IsReferenceAssembly(assembly.Metadata, assembly.FileName);

Loading…
Cancel
Save