Open nzain opened 4 years ago
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.'
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?
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>
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.'
@nzain: Could you provide a project with a reference to a different public .Net 2.0 WinCE-compatible framework dll that reproduces the problem?
@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 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.
@ryalanms can you reproduce the problem with the data linked above?
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.
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).
@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...
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
.
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]
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.
6.0.100-preview.6.21355.2
does not fix it, just tested it.
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.
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?
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.
Thanks @jw-suh for the explanation.. stupid me :) It works with my sample, because the WinCE objects are not used in the UI.
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.
This should have been fixed with https://github.com/dotnet/corefx/pull/42768. I am able to reproduce the failure with @jw-suh's test project.
/cc @dotnet/wpf-developers
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 }
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):
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.
@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?
@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?
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).
@vitek-karas and @agocke: Is the runtime behavior different?
/cc @SamBent
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.
Thanks, @vitek-karas. @SamBent: We can discuss this in triage.
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?
@singhashish-wpf has there been any more discussion regarding this?
@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.
@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.
3.1.401
and5.0.100-preview.8.20417.9
netcoreapp3.1
andnet50
dotnet build
from command lineThis is essentially a duplicate of the closed https://github.com/dotnet/wpf/issues/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)or (SDK 5.0.100-preview.8.20417.9)
Expected behavior:
dotnet build
runs fine.Minimal repro:
dotnet new wpf
netcoreapp3.1
ornet50
<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 number16.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 msbuild16.8.0.xxx
).