@@ -79,6 +79,19 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
7979 return $ ".NETFramework,Version=v{ assemblyDefinition . Version . ToString ( 2 ) } ";
8080 case "netstandard" :
8181 return $ ".NETStandard,Version=v{ assemblyDefinition . Version . ToString ( 2 ) } ";
82+ case "System.Runtime" :
83+ case "System.Private.CoreLib" :
84+ {
85+ string version = GetDotNetCoreVersion ( assemblyDefinition . Version ) ;
86+ if ( version != null )
87+ {
88+ return $ ".NETCoreApp,Version=v{ version } ";
89+ }
90+ else
91+ {
92+ break ;
93+ }
94+ }
8295 }
8396 }
8497
@@ -92,42 +105,20 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
92105 string version ;
93106 switch ( metadata . GetString ( r . Name ) )
94107 {
95- case "netstandard " :
108+ case "mscorlib " :
96109 version = r . Version . ToString ( 2 ) ;
97- return $ ".NETStandard ,Version=v{ version } ";
110+ return $ ".NETFramework ,Version=v{ version } ";
98111 case "System.Runtime" :
99- // System.Runtime.dll uses the following scheme:
100- // 4.2.0 => .NET Core 2.0
101- // 4.2.1 => .NET Core 2.1 / 3.0
102- // 4.2.2 => .NET Core 3.1
103- // 5.0.0+ => .NET 5+
104- if ( r . Version >= new Version ( 4 , 2 , 0 ) )
112+ case "System.Private.CoreLib" :
113+ version = GetDotNetCoreVersion ( r . Version ) ;
114+ if ( version != null )
105115 {
106- if ( r . Version . Major >= 5 )
107- {
108- version = r . Version . ToString ( 2 ) ;
109- }
110- else if ( r . Version . Major == 4 && r . Version . Minor == 2 )
111- {
112- version = r . Version . Build switch {
113- <= 0 => "2.0" ,
114- 1 => "3.0" ,
115- _ => "3.1"
116- } ;
117- }
118- else
119- {
120- version = "2.0" ;
121- }
122116 return $ ".NETCoreApp,Version=v{ version } ";
123117 }
124118 else
125119 {
126120 continue ;
127121 }
128- case "mscorlib" :
129- version = r . Version . ToString ( 2 ) ;
130- return $ ".NETFramework,Version=v{ version } ";
131122 }
132123 }
133124 catch ( BadImageFormatException )
@@ -136,6 +127,24 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
136127 }
137128 }
138129
130+ // We check for netstandard separately because .NET Core/Framework assemblies can reference it.
131+ foreach ( var h in metadata . AssemblyReferences )
132+ {
133+ try
134+ {
135+ var r = metadata . GetAssemblyReference ( h ) ;
136+ if ( r . PublicKeyOrToken . IsNil || metadata . GetString ( r . Name ) is not "netstandard" )
137+ continue ;
138+
139+ string version = r . Version . ToString ( 2 ) ;
140+ return $ ".NETStandard,Version=v{ version } ";
141+ }
142+ catch ( BadImageFormatException )
143+ {
144+ // ignore malformed references
145+ }
146+ }
147+
139148 // Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)
140149 if ( assemblyPath != null )
141150 {
@@ -185,6 +194,24 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
185194 return string . Empty ;
186195 }
187196
197+ static string GetDotNetCoreVersion ( Version assemblyVersion )
198+ {
199+ // System.Runtime.dll and System.Private.CoreLib.dll use the following scheme:
200+ // 4.1.0 => .NET Core 1.0 / 1.1
201+ // 4.2.0 => .NET Core 2.0
202+ // 4.2.1 => .NET Core 2.1 / 3.0
203+ // 4.2.2 => .NET Core 3.1
204+ // 5.0.0+ => .NET 5+
205+ return ( assemblyVersion . Major , assemblyVersion . Minor , assemblyVersion . Build ) switch {
206+ ( 4 , 1 , 0 ) => "1.1" ,
207+ ( 4 , 2 , 0 ) => "2.0" ,
208+ ( 4 , 2 , 1 ) => "3.0" ,
209+ ( 4 , 2 , 2 ) => "3.1" ,
210+ ( >= 5 , _, _) => assemblyVersion . ToString ( 2 ) ,
211+ _ => null
212+ } ;
213+ }
214+
188215 public static bool IsReferenceAssembly ( this MetadataFile assembly )
189216 {
190217 return IsReferenceAssembly ( assembly . Metadata , assembly . FileName ) ;
0 commit comments