-
-
Notifications
You must be signed in to change notification settings - Fork 649
Description
An assembly built to target the .Net Framework expects to resolve system references in the GAC; however a .net (core) program using Cecil to manipulate that assembly resolves them to the trusted locations under dotnet/shared. The two files will not always match up.
Here's an example -- ClassLibrary.csproj builds a WPF-consuming assembly that references WindowsBase.dll v4.0.0.0 in the GAC. CecilGAC.csproj is a simple .net6.0 program that reads and rewrites the ClassLibrary1.dll assembly.
The program fails during write with
Mono.Cecil.ResolutionException: Failed to resolve System.Windows.Threading.DispatcherPriority
at Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
...
because a WindowsBase.dll v4.0.0.0 has been found within C:\Program Files\dotnet\shared\Microsoft.NETCore.App; but that assembly is a stub containing only
internal class <Module>
{
}However, if CecilGAC.csproj is modified to be
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net48" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
</ItemGroup>
</Project>
building against .Net Framework v4.8, the write operation finds the expected file in the GAC, and the type resolution completes successfully.
Because a suitable strong-named assembly has been found in the ,net core case, a simple reactive approach such as overriding the AssemblyResolver to handle resolution failures by checking the GAC (if present) does not resolve the issue; the necessary fix would be to replace the #if NET_CORE compile-time logic with a runtime selection based on the [TargetFramework] attribute value of the assembly being manipulated.
[ADDED] An alternative would be to recognise such a pure stub assembly and consider it an assembly resolution failure; this form of stub seems to be a standard pattern for GUI-related assemblies.