Wpf: Preview 7: 'Could not find assembly 'mscorlib...' in Microsoft.WinFX.targets

Created on 29 Jul 2019  路  19Comments  路  Source: dotnet/wpf

Hi! On .Net Core 3.0 Preview 7, VS 16.3 Preview 1.

My only error for my WPF project is below (a similar WinForms project that depends on the same assemblies is building and running fine). I have no explicit dependencies on mscorlib, but possibly an implicit one via a 3rd party dependency. Is this a forwarding issue specific to WPF? If so, how to resolve? Thanks!!

Error MC1000 Unknown build error, 'Could not find assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. Either explicitly load this assembly using a method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly.' C:\Program Files\dotnet\sdk\3.0.100-preview7-012821\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets 243

C:\Program Files\dotnet\sdk\3.0.100-preview7-012821\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(243,9): error MC1000: Unknown build error, 'Could not find assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. Either explicitly load this assembly using a method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly.'

Done executing task "MarkupCompilePass1" -- FAILED.

```
Language="$(Language)"
UICulture="$(UICulture)"
ApplicationMarkup="@(ApplicationDefinition)"
SplashScreen="@(SplashScreen)"
LanguageSourceExtension="$(DefaultLanguageSourceExtension)"
PageMarkup="@(Page)"
ContentFiles="@(Content)"
AssemblyName="$(AssemblyName)"
OutputType="$(OutputType)"
AssemblyVersion="$(AssemblyVersion)"
AssemblyPublicKeyToken="$(AssemblyPublicKeyToken)"
References="@(ReferencePath)"
RootNamespace="$(RootNamespace)"
KnownReferencePaths="$(MSBuildBinPath);$(TargetFrameworkDirectory);@(_TargetFrameworkSDKDirectoryItem);@(KnownReferencePaths)"
AssembliesGeneratedDuringBuild="@(AssembliesGeneratedDuringBuild)"
AlwaysCompileMarkupFilesInSeparateDomain="$(AlwaysCompileMarkupFilesInSeparateDomain)"
HostInBrowser="$(HostInBrowser)"
LocalizationDirectivesToLocFile="$(LocalizationDirectivesToLocFile)"
ContinueOnError="$(_IntellisenseOnlyCompile)"
SourceCodeFiles="@(Compile)"
DefineConstants="$(DefineConstants)"
ExtraBuildControlFiles="@(ExtraBuildControlFiles)"
XamlDebuggingInformation="$(XamlDebuggingInformation)"
IsRunningInVisualStudio="$(BuildingInsideVisualStudio)"
OutputPath="$(IntermediateOutputPath)">

          <Output ItemName="GeneratedBaml" TaskParameter="GeneratedBamlFiles"/>
          <Output ItemName="GeneratedLocalizationFiles" TaskParameter="GeneratedLocalizationFiles" />
          <Output PropertyName="_RequireMCPass2ForMainAssembly" TaskParameter="RequirePass2ForMainAssembly" />
          <Output PropertyName="_RequireMCPass2ForSatelliteAssemblyOnly" TaskParameter="RequirePass2ForSatelliteAssembly" />
          <Output ItemName="Compile" TaskParameter="GeneratedCodeFiles" />

          <!-- Keep a list of all the generated files, it is used to clean up for a next clean build -->
          <Output ItemName="FileWrites" TaskParameter="AllGeneratedFiles" />

          <Output ItemName="_GeneratedCodeFiles"
                  TaskParameter="GeneratedCodeFiles" />


    </MarkupCompilePass1>

```

_Originally posted by @dcuccia in https://github.com/dotnet/core/issues/3075#issuecomment-515806022_

/cc @ryalanms, @grubioe
/cc @dotnet/wpf-developers

Most helpful comment

Thanks for the repro @dcuccia. The problem is that PresentationBuildTasks is not accommodating 'retargetable' assembly references.

// Metadata version: v4.0.30319
.assembly extern retargetable mscorlib
{
.publickeytoken = (7C EC 85 D7 BE A7 79 8E ) // |.....y.
.ver 2:0:5:0
}

Version 4.0.1 of pulls in CommoneServiceLocator, which contains Microsoft.Practices.ServiceLocation.dll. Microsoft.Practices.ServiceLocation.dll was built against mscorlib version 2.0.5.0.

At compile time PresentationBuildTasks loads assemblies in a 'reflection-only' context (for the type table, etc). When any types in reflection-only assemblies have dependencies on other assemblies, MetadataLoadContext's assembly resolver is invoked to find the required dependent assembly. To match an assembly in the reference list, the assembly name, version, and public key token must match. If the names and public key tokens match, the highest version of the assembly will be loaded in to the reflection-only context. If the public key token of the requested assembly does not match any assembly in the reference list, the markup compilation task will fail.

A new MetadataAssemblyResolver needs to be added that supports retargetable references, or at least supports a retargetable mscorlib reference. If a different, newer version of mscorlib is available at compile time, we should ignore the public key token mismatch, when the mscorlib reference is marked 'retargetable'.

All 19 comments

Thanks. I misspoke slightly in the OP. I have three dependencies that are not shared with the (working) WinForms app:

MahApps.Metro.Resources (0.6.1)
Microsoft.Toolkit.Wpf.UI.Controls (5.1.0)
Microsoft.Toolkit.Wpf.UI.Controls.WebView (5.1.0)

Confirming that the libraries above don't impact this issue. Simply creating a file->new .Net Core Wpf app and referencing a shared Core 3.0 class library causes this error at MarkupCompilePass1 in Microsoft.WinFx.targets, whereas the same reference for a .Net Core WinForms app does not cause the issue.

Thanks @dcuccia. For a standard netcore assembly built from the netcore template, I see System.Runtime in the metadata, not mscorlib, and a WPF test project referencing the netcore library in markup is building. Is there any way you could you share a repro project? This looks like a bug in PBT. Thanks.

Hi @ryalanms , I'll try to create a repro. The library dependency is proprietary, but it's dependencies aren't so maybe I can recreate the issue independently.

Can report that upgrading Nuget package Microsoft.Practices.Unity 4.0.1 to Unity 5.11.1 resolves this build error. Attaching example of broken solution.
WpfApp1.zip

I also see a similar behaviour in preview7 and preview8 with targetframework net461.

This will reproduce it

dotnet new wpf
change TargetFramework to net461
dotnet add package Common.Logging --version 3.4.1
dotnet build

You can also clone https://github.com/hsorbo/wpfbug

Thanks for the repro @dcuccia. The problem is that PresentationBuildTasks is not accommodating 'retargetable' assembly references.

// Metadata version: v4.0.30319
.assembly extern retargetable mscorlib
{
.publickeytoken = (7C EC 85 D7 BE A7 79 8E ) // |.....y.
.ver 2:0:5:0
}

Version 4.0.1 of pulls in CommoneServiceLocator, which contains Microsoft.Practices.ServiceLocation.dll. Microsoft.Practices.ServiceLocation.dll was built against mscorlib version 2.0.5.0.

At compile time PresentationBuildTasks loads assemblies in a 'reflection-only' context (for the type table, etc). When any types in reflection-only assemblies have dependencies on other assemblies, MetadataLoadContext's assembly resolver is invoked to find the required dependent assembly. To match an assembly in the reference list, the assembly name, version, and public key token must match. If the names and public key tokens match, the highest version of the assembly will be loaded in to the reflection-only context. If the public key token of the requested assembly does not match any assembly in the reference list, the markup compilation task will fail.

A new MetadataAssemblyResolver needs to be added that supports retargetable references, or at least supports a retargetable mscorlib reference. If a different, newer version of mscorlib is available at compile time, we should ignore the public key token mismatch, when the mscorlib reference is marked 'retargetable'.

@ryalanms, How hard would it be to augment the MetadataAssemblyResolver used by PBT to support retargetable references? Is this something we can do as a small + scoped + safe change that would fit within the scope of 3.0 ?

/cc @rladuca, @grubioe

When MetadataLoadContext was expanded to include a default assembly resolver, we removed PBT's custom resolver and replaced it with MetadataLoadContext's default resolver. So accommodating 'retargetable' assemblies will require a new resolver in PBT unless or until support for 'retargetable' is added to MetadataLoadContext's PathAssemblyResolver. Adding a new resolver class should be safe because the PathAssemblyResolver code can be re-used, along with a slight modification to check for 'retargetable' when comparing PKTs.

@ryalanms it seems like you should just be able to wrap PathAssemblyResolver with code that first checks for a retargetable assembly and handles those cases while passing any other scenarios directly to an instance of PathAssemblyResolver.

I'm not sure which preview broke this. But I know it worked fine in Preview 3.
Preview 7 and 8 both give the same error on this app: https://github.com/hallatore/Netling/

@hallatore: The assembly matching became more restrictive when the resolver was switched to PathAssemblyResolver, which requires public key token and version to match.

@rladuca: Handling just the retargetable assembly resolutions and passing other Resolve requests to an instance of PathAssemblyResolver would require as many lines as rewriting the resolver.

@ryalanms Is there a way around this? The error message isn't exactly self explaining, so I'm not sure what I can do to fix this. Do I need to wait for it to get fixed in the SDK?

I'm guessing the issue lies with me using older net461 nuget packages in WPF. But then again isn't that kinda the point with WPF in 3.0?

Unfortunately there isn't a work-around. During XAML compilation, if an assembly is loaded in ReflectionOnly context that was built against an older version of mscorlib, the compiler will fail to resolve the older mscorlib version.

I'll see if we can get this in.

I agree with @rladuca that we should just fix this in CoreFX.

https://github.com/dotnet/corefx/issues/40523#issuecomment-525405471

I brought this up in tactics and their indication was won't fix for now and consider for 3.1 if we get more feedback on this blocking multiple packages.

I've ran into the same issue when creating my first WPF core 3.1 application. As soon as I add a manual dll reference

<Reference Include="SomethingOld" HintPath="$(SolutionDir)Externals\SomethingOld.dll" />

with old proprietary net2.0 stuff (even compatible to dead WinCE), the compiler shows this error

Unknown build error, 'Could not find assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=969db8053d3322ac'. Either explicitly load this assembly using a method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly.'
C:\Program Files\dotnet\sdk\3.1.301\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets   225
  • I'm not the author of this old proprietary stuff, the original author has retired :)
  • We cannot roll our own (more than one person-year work).

Looking at https://github.com/dotnet/runtime/issues/30663 tells me it was set to "won't fix" for 3.0, but the last comments say it has been merged and went live into servicing fix. However, I'm running dotnet core 3.1.301 commit 7feb845744 (the latest I can download) and it still occurs. Suggestions?

@nzain I recommend opening a new issue. This particular symptom has seen a few newer (and more prominent) iterations and focused efforts at troubleshooting. A new issue will provide folks a place to reference more recent investigations and dig into your specific problem. Reactivating/opening this issue may not be ideal (since nobody is going to 'fix' 3.0preview7 now 馃榿).

Was this page helpful?
0 / 5 - 0 ratings