Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft.WinFX.targets Unknown build error Could not find assembly 'mscorlib' #3465

Open
nzain opened this issue Sep 8, 2020 · 33 comments
Open
Assignees
Labels
Bug Product bug (most likely) Investigate Requires further investigation by the WPF team.
Milestone

Comments

@nzain
Copy link

nzain commented Sep 8, 2020

  • .NET Core Version: happens both with 3.1.401 and 5.0.100-preview.8.20417.9
  • Windows version: Win 10 (1909) 10.0.18363
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: for TFMs netcoreapp3.1 and net50
  • Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No, Visual Studio is not involved, only dotnet build from command line

This is essentially a duplicate of the closed #3183 ; the ticket was closed, although it was not resolved and I cannot re-open it. @ryalanms told me to reactivate when I see the issue again. Well, it has never been resolved for me. Sorry for the double-issue.

Problem description:
WPF core app doesn't build when adding a direct <Reference .../> to an old .Net 2.0 WinCE-compatible framework dll.
(Why would you do that? Expensive, proprietary dll from 3rd party, we can't live without it, author has retired)

Actual behavior:
dotnet build fails with either (SDK 3.1.401)

C:\Program Files\dotnet\sdk\3.1.401\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(225,9): 
error MC1000: 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.'

or (SDK 5.0.100-preview.8.20417.9)

C:\Program Files\dotnet\sdk\5.0.100-preview.8.20417.9\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(240,9):
error MC1000: 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.'

Expected behavior:
dotnet build runs fine.

Minimal repro:

  • dotnet new wpf
  • TFM either netcoreapp3.1 or net50
  • Add a library reference to an old .Net Framework 2.0 WinCE library like so: <Reference Include="SomethingOld" HintPath="SomethingOld.dll" />
  • dotnet build
    Unfortunately I can't publish the proprietary dll here. It is built for .Net Framework 2 with WinCE compatibility.

@ryalanms said that is should be fixed in 3.1.401, but it is not fixed. He mentioned another version number 16.7.1 - unclear what for. Visual Studio is not involved and I've tested with different MSBuild versions too (the 5.0 preview comes with msbuild 16.8.0.xxx).

@nzain
Copy link
Author

nzain commented Sep 9, 2020

Problem is not fixed in the new 3.1.402 dotnet SDK:

C:\Program Files\dotnet\sdk\3.1.402\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(225,9): 
error MC1000: 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.'

@ryalanms
Copy link
Member

ryalanms commented Sep 9, 2020

Thank you for the report, @nzain. Sorry that the previous fix did not cover this scenario.

Did your project compile with a previous version of .NET Core?

@nzain
Copy link
Author

nzain commented Sep 10, 2020

Good question - all my previous experiments with WPF core were rather simple. Thus, I don't know if it worked with an older version. However, I have a netcoreapp3.1 console application working on the exact same dlls for a long time. The <Project Sdk="Microsoft.NET.Sdk"> works fine. Thus, it seems to be a WPF specific issue. After dotnet new wpf the following fails to compile on 3.1.402:

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="SurvComCE" HintPath="SurvComCE.dll" />
  </ItemGroup>
</Project>

When I create a dotnet new console project, the following works just fine:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="SurvComCE" HintPath="SurvComCE.dll" />
  </ItemGroup>
</Project>

@nzain
Copy link
Author

nzain commented Sep 15, 2020

The problem persists with the latest 5.0.100-rc.1.20452.10 release canditate:

C:\Program Files\dotnet\sdk\5.0.100-rc.1.20452.10\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(240,9): 
error MC1000: 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.'

@ryalanms ryalanms self-assigned this Oct 12, 2020
@ryalanms
Copy link
Member

@nzain: Could you provide a project with a reference to a different public .Net 2.0 WinCE-compatible framework dll that reproduces the problem?

@nzain
Copy link
Author

nzain commented Oct 14, 2020

@ryalanms please request a private copy vie e-mail (patrick_stalphATtrimble.com).

For the sake of completeness: the problem persists with the latest 5.0.100-rc.2.20479.15 SDK.

@ryalanms ryalanms added the Bug Product bug (most likely) label Oct 15, 2020
@nzain
Copy link
Author

nzain commented Nov 11, 2020

@ryalanms I was able to create a Visual Studio 2008 csproj targeting .net v2.0 compact framework to reproduce the issue. The following zip file contains a VS2008 solution and the compiled dll (look for the bin\debug folder). If you want to compile yourself, you have to install Visual Studio 2008 and Microsoft .Net Compact Framework as well.
VS2008-WinCE-lib.zip

As soon as you reference the above dll from a WPF Core project (tried today with net5-windows on the new 5.0.100 SDK) you will get the error.

Furthermore, a manual binding redirect for mscorlib does not work. I added the following App.config with no effect:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="mscorlib" culture="neutral" publicKeyToken="969db8053d3322ac" />
        <bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Hope this helps to further diagnose the problem.

@nzain
Copy link
Author

nzain commented Dec 2, 2020

@ryalanms can you reproduce the problem with the data linked above?

@JensNordenbro
Copy link

I can confirm the same: One dll having a dependency to a thirdparty compact framework assembly that we "cannot easilly replace" gave the same results.

@nzain
Copy link
Author

nzain commented Jan 20, 2021

This issue is blocking all potential migration work, there is no workaround up to now, and we are stuck on net 4.8 framework. I understand that developer resources are limited (very limited for WPF especially), but there has been no progress for several month! It would be nice to get some feedback on this at least (can you reproduce it, workaround ideas, milestone expectation).

@JensNordenbro
Copy link

@nzain, In our case I managed to stub out our dependency, just mimicing the public api.
This ofcourse requires the code not to be the backbone of the application and of course later things needs to be re-implemented unless this is fixed and compatible with net5+. (winforms stuff might not due to reduced api coverage in >= netcore3.1 )

Maybe this approach will work for you, maybe not.... :)

Me, I have given up on the old thirdparty dependencies for CF, and probably we will either contact suppliers for buy-out of source code or just re-implement / replace the dependencies...

@ryalanms ryalanms added the Investigate Requires further investigation by the WPF team. label Feb 3, 2021
@nzain
Copy link
Author

nzain commented Feb 23, 2021

The problem remains unresolved with dotnet-sdk-6.0.100-preview.1.21103.13-win-x64 and MS Build 16.9.0-preview-21103-02+198f3f262.

@nzain
Copy link
Author

nzain commented May 26, 2021

Dotnet 6 Preview 4 - problem remains. @ryalanms were you able to reproduce the problem with the files I shared?

C:\Program Files\dotnet\sdk\6.0.100-preview.4.21255.9\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(222,9): 
error MC1000: 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.'  [D:\Downloads\DotnetCoreIssue\DotnetCoreIssue\DotnetCoreIssue.csproj]

@jw-suh
Copy link

jw-suh commented Jun 29, 2021

Since I have run into the same problem, I want to add the little information I have not yet found in the issues.

The Problem does not occur by creating a WPF Project. A completely empty WPF project will compile. As soon as you add any Page, Window etc. the project breaks.

Find attached an empty WPF library and a WPF library with a Page:
EmptyWpfApp.zip
NonEmptyWpfApp.zip

I hope this information helps at least narrowing down the error cause.

@nzain
Copy link
Author

nzain commented Jul 15, 2021

6.0.100-preview.6.21355.2 does not fix it, just tested it.

@ThomasGoulet73
Copy link
Contributor

Here's a workaround that you can add to your csproj that you could use until it is fixed:

  <Target Name="RemoveMdpNetApi" BeforeTargets="MarkupCompilePass1">
    <ItemGroup>
      <_TempWPFReference Include="@(ReferencePath)" />
      <ReferencePath Remove="@(ReferencePath)" Condition="'%(ReferencePath.Filename)'=='MdpNetApi'" />
    </ItemGroup>
  </Target>
  
  <Target Name="RestoreMdpNetApi" AfterTargets="MarkupCompilePass2">
    <ItemGroup>
      <ReferencePath Remove="@(ReferencePath)" />
      <ReferencePath Include="@(_TempWPFReference)" />
    </ItemGroup>
  </Target>

This basically removes the .Net Framework 2.0 CE from being loaded in the markup compilation. The only thing is that you cannot use anything from your .Net Framework 2.0 CE dll inside your xaml.

@nzain
Copy link
Author

nzain commented Jul 19, 2021

Thanks @ThomasGoulet73 for suggesting a workaround. Unfortunately, it does not work. I tested with my sample project as posted somewhere above and net5.0.7 SDK. Where did you get that 'MdpNetApi' idea?

@jw-suh
Copy link

jw-suh commented Jul 19, 2021

Hey @nzain sorry for causing this confusion. 'MdeNetApi was the reference I used in my sample somewhere above to reproduce the issue. I guess the workaround should use anyone's specific reference name. I'll give this workaround a go with my sample as soon as I have the time for it.

@nzain
Copy link
Author

nzain commented Jul 19, 2021

Thanks @jw-suh for the explanation.. stupid me :) It works with my sample, because the WinCE objects are not used in the UI.

@jw-suh
Copy link

jw-suh commented Jul 19, 2021

Yep, just tried the workaround from @ThomasGoulet73 in my (very limited) sample. And it worked as well. Sadly, I won't be able to test it in my production case any time soon, since we had to move on and found a different solution that did not require any old DLL. For now, I would expect it to work, since the xaml didn't use any part of said DLL.

@ryalanms
Copy link
Member

This should have been fixed with dotnet/corefx#42768. I am able to reproduce the failure with @jw-suh's test project.

/cc @dotnet/wpf-developers

@ryalanms
Copy link
Member

The assembly reference in the metadata must include 'retargetable' or there is no way for the resolver to know that it has permission to use a newer version of that assembly:

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

Here is the manifest for the dll used in the repro project. Note that it is missing retargetable.

// Metadata version: v2.0.50727
.module extern MdpApi.dll
.assembly extern mscorlib
{
.publickeytoken = (96 9D B8 05 3D 33 22 AC ) // ....=3".
.ver 2:0:0:0
}

@ThomasGoulet73
Copy link
Contributor

I just tried applying the retargetable flag that @ryalanms talked about and it fixed the bug in the sample @jw-suh provided.

I did that by doing ILDasm -> Add retargetable to mscorlib -> ILAsm.

Here are the steps that I followed (These might vary depending on the assemblies you are trying to modify):

  1. ildasm MdpNetApi.dll /OUT=MdpNetApi.il
  2. Open MdpNetApi.il in a text editor and add retargetable to mscorlib (It's located in the first lines of the file).
  3. ilasm MdpNetApi.il /RESOURCE=MdpNetApi.res /OUTPUT="MdpNetApi_New.dll" /DLL

This is probably not the best solution but since its about supporting a legacy framework and the referenced assembly probably does not get many updates, I'd say that it's good enough.

@nzain
Copy link
Author

nzain commented Aug 17, 2021

@ryalanms the fix you mentioned has been merged into the 3.1 release branch in January 2020. When do you expect to see this in a net 5/6 release?

"retargetable" - why do WPF apps require this, but console apps don't?

@ryalanms
Copy link
Member

ryalanms commented Aug 17, 2021

@ericstj: Does a console application allow referencing assemblies built against a different version of mscorlib that do not use the 'retargetable' flag? Should WPF support this?

@ericstj
Copy link
Member

ericstj commented Aug 17, 2021

Different versions, yes. Retargetable is used to allow assemblies to change public key. By default the loader should permit newer versions of an assembly to satisfy older references. https://github.com/dotnet/runtime/blob/82f7144f791314885c0e4e86f16e579357bfe7e3/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/PathAssemblyResolver.cs#L75 cc @steveharter

"retargetable" - why do WPF apps require this, but console apps don't?

I wouldn't expect the runtime to permit a different public key token without the retargetable bit, perhaps @vitek-karas or @agocke might know if it does (or if it allows this for mscorlib specially).

@ryalanms
Copy link
Member

@vitek-karas and @agocke: Is the runtime behavior different?

/cc @SamBent

@vitek-karas
Copy link
Member

As far as I can tell the runtime ignores retargetable flag. It will recognize it and store it and if asked can produce the full qualified name of the assembly with the Retargetable=yes section in it. It can also parse such a name. But it doesn't use the value for anything.

Also, runtime ignores public keys when binding assemblies. Meaning:

    AssemblyLoadContext.Default.LoadFromAssemblyPath(@"TestLib.dll");
    // Loaded "TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a5aa501ed74f54b5"

    // Notice the different public key
    var asmname = new AssemblyName("TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8c18119b32e50707");
    var asmref = AssemblyLoadContext.Default.LoadFromAssemblyName(asmname);
    // No failure.
    // asmref is "TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a5aa501ed74f54b5" - so the one already loaded above

Also runtime doesn't verify the strong name in any way. It does persist the information (as seen above, the public keys are part of the assembly names), so it can be used in the app code to verify, but it will not do so itself.

@ryalanms
Copy link
Member

Thanks, @vitek-karas. @SamBent: We can discuss this in triage.

@ericstj
Copy link
Member

ericstj commented Aug 27, 2021

One other good piece of data to gather here: does the compiler permit it? If CSC is also ignoring publicKey it may be fair to ask SRM to relax the constraint. What happens in a normal net5 project where you build against this assembly and try to interact with its API that references types that would live in mscorlib?

@ryalanms ryalanms added this to the 6.0.0 RC2 milestone Aug 27, 2021
@ryalanms ryalanms modified the milestones: 6.0.0 RC2, .NET 6.0 Servicing Sep 8, 2021
@vishalmsft vishalmsft added this to To do in .NET 6.0 Servicing Oct 13, 2021
@vishalmsft vishalmsft removed this from To do in .NET 6.0 Servicing Oct 13, 2021
@djonesCenterEdge
Copy link

@singhashish-wpf has there been any more discussion regarding this?

@singhashish-wpf
Copy link
Member

@djonesCenterEdge No, there have not been any further updates on this, However the workarounds are already stated above. Let us know if you think those are not acceptable.

@djonesCenterEdge
Copy link

@singhashish-wpf the workarounds stated above don't actually work, as the people who tried them also stated above. We managed to make it work by adding a dependency to System.Runtime.CompilerServices.Unsafe and using msbuild instead of dotnet to build our our solutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Product bug (most likely) Investigate Requires further investigation by the WPF team.
Projects
Development

No branches or pull requests

9 participants