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

System.Windows.Markup.XamlParseException in System.Runtime when published trimmed #1917

Closed
sbomer opened this issue Mar 24, 2021 · 14 comments
Closed

Comments

@sbomer
Copy link
Member

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @Symbai on Tuesday, March 23, 2021 4:32:28 PM

Description

Publishing a WPF application using the trim unused assemblies option (VS -> Build dialog) throws a System.Windows.Markup.XamlParseException on start of the application. Publishing untrimmed works fine.

Configuration

image

Other information

 OS Name:     Windows
 OS Version:  10.0.19042
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.201\

Host (useful for support):
  Version: 5.0.4
  Commit:  f27d337295
System.Windows.Markup.XamlParseException: An exception was thrown by calling the constructor for type "Aaaa.MainWindow" that matches the specified binding restrictions.

 ---> System.TypeInitializationException: The type initializer for 'System.Windows.Window' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'System.Windows.FrameworkElement' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'System.Windows.Documents.TextElement' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'System.Windows.Documents.Typography' threw an exception.
 ---> System.IO.FileNotFoundException:

File name: 'System.Runtime, Version = 5.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a'
   at System.Windows.Media.TextFormatting.TextRunTypographyProperties.OnPropertiesChanged ()
   at MS.Internal.Text.TypographyProperties.ResetProperties ()
   at MS.Internal.Text.TypographyProperties..ctor ()
   at System.Windows.Documents.Typography..cctor ()
   --- End of inner exception stack trace ---
   at System.Windows.Documents.TextElement..cctor ()
   --- End of inner exception stack trace ---
   at System.Windows.FrameworkElement..cctor ()
   --- End of inner exception stack trace ---
   at System.Windows.Window..cctor ()
   --- End of inner exception stack trace ---
   at System.Windows.Window..ctor ()
   at Aaaa.MainWindow..ctor ()
   --- End of inner exception stack trace ---
   at System.Windows.Markup.XamlReader.RewrapException (Exception e, IXamlLineInfo lineInfo, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.Load (XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml (XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   at System.Windows.Markup.XamlReader.LoadBaml (Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at System.Windows.Application.LoadBamlStreamWithSyncInfo (Stream stream, ParserContext pc)
   at System.Windows.Application.LoadComponent (Uri resourceLocator, Boolean bSkipJournaledProperties)
   at System.Windows.Application.DoStartup ()
   at System.Windows.Application. <. ctor> b__1_0 (Object unused)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall (Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen (Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

The trim feature has removed the following files, several of them sounds pretty much mandatory for EVERY app to me and shouldn't be trimmed:
image

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321

  • Please respond to @dotnet-issue-labeler[bot].

From @dotnet-issue-labeler[bot] on Tuesday, March 23, 2021 4:32:31 PM

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @Symbai on Wednesday, March 24, 2021 8:32:22 AM

@danmoseley Why has this been moved to WPF repo? The WPF team has nothing to do with the trimming feature and the issue is that the trimming feature has removed assemblies it shouldn't. It should get reviewed by the developers who are responsible for the logic of the trimming feature

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @danmoseley on Wednesday, March 24, 2021 8:41:04 AM

My assumption was that this was due to WPF assemblies not supporting trimming because they have not been annotated ie they have linker warnings.

@eerhardt thoughts?

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @ThomasGoulet73 on Wednesday, March 24, 2021 12:55:05 PM

Here is the target I use to configure trimming in my WPF application:

<Target Name="ConfigureTrimming" BeforeTargets="PrepareForILLink">
  <ItemGroup>
    <ManagedAssemblyToLink Condition="'%(Filename)' == 'System.Runtime' Or '%(Filename)' == 'System.Runtime.Extensions' Or '%(Filename)' == 'System.Diagnostics.Debug'">
      <IsTrimmable>false</IsTrimmable>
    </ManagedAssemblyToLink>
  </ItemGroup>
</Target>

You can copy/paste it in your main csproj and if you still have an exception, you can add the trimmed assembly in the condition using Or '%(Filename)' == 'NAME_OF_YOUR_ASSEMBLY'.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @ThomasGoulet73 on Wednesday, March 24, 2021 1:04:46 PM

@danmoseley If I understood the trimming correctly, the WPF assemblies are not trimmed but the assemblies from the BCL can be trimmed. That's why the exception is for an assembly from the BCL.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @Symbai on Wednesday, March 24, 2021 2:02:31 PM

Thank you but that just exclude the files manually and did not explain/solve the issue that the trimming feature is working absolutely incorrectly. Except for hello world applications I've never seen trimming feature that does not crash an application and in this case its deleting base assemblies. My code uses the File class literately everywhere and still its deleting System.File.IO. My code uses WebClient a lot and still its deleting System.Net. I have async code a lot still its deleting System.Threading.Task

Why is System.Data, System.Runtime or mscorlib deleted? I've never seen a .NET app running without these. There is some serious issue in the trimming feature logic that needs to be fixed.

Only third party assemblies or some "rare edge cases" devs should be told to manually exclude them. Otherwise its not a solution

//edit: Is the trimming feature meant to support WPF? Does it understand XAML binding, MVVM patterns? I have the horrible feeling it might not but I'm hoping I'm wrong.

See my comment below

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @ThomasGoulet73 on Wednesday, March 24, 2021 2:15:36 PM

Thank you but that just exclude the files manually and did not explain/solve the issue that the trimming feature is working absolutely incorrectly. Except for hello world applications I've never seen trimming feature that does not crash an application and in this case its deleting base assemblies. My code uses the File class literately everywhere and still its deleting System.File.IO. My code uses WebClient a lot and still its deleting System.Net. I have async code a lot still its deleting System.Threading.Task

Why is System.Data, System.Runtime or mscorlib deleted? I've never seen a .NET app running without these. There is some serious issue in the trimming feature logic that needs to be fixed.

Many of the dlls in your screenshot are only facades, they do not actually contain code. The code is in other assemblies, mostly System.Private.CoreLib. You can see it for yourself by peeking inside the content of a trimmed dll with a decompiler like dotPeek.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @ThomasGoulet73 on Wednesday, March 24, 2021 2:20:30 PM

//edit: Is the trimming feature meant to support WPF? Does it understand XAML binding, MVVM patterns? I have the horrible feeling it might not but I'm hoping I'm wrong.

I don't think it's officially supported (See the "in preview" part in the publish profile), though a WPF or .Net team member can correct me.

I can say that I didn't really have any problem with trimming except for the target that I posted.

Also, I think there is an effort to annotate the BCL and frameworks like WPF for trimming in .Net 6. See dotnet/wpf#3811. These annotations can help the linker see what is not required, even with reflection.

Edit: I had success using MVVM, Bindings, Reflection, File IO and async Code using the linker. Even with <TrimMode>link</TrimMode>.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @Symbai on Wednesday, March 24, 2021 2:28:22 PM

I was wrong, I apologize. After adding your code the trimmed applications works perfectly fine (as far as I can tell). So yes there is a problem with detecting these 3(?) assemblies in the trimming logic only.

@sbomer
Copy link
Member Author

sbomer commented Mar 24, 2021


Issue moved from dotnet/wpf#4321


From @eerhardt on Wednesday, March 24, 2021 3:20:16 PM

This is a bug in the trimming tool. These assemblies should not be trimmed. I believe this issue should be moved to the https://github.com/mono/linker/ repo.

Another interesting fact is that if you upgrade to 6.0, the app breaks even worse because TrimMode=link is now enabled by default. The first error I am getting in 6.0 is:

System.MissingMethodException: 'Method not found: 'Void System.Runtime.InteropServices.GCHandle.set_Target(System.Object)'.'

cc @marek-safar @vitek-karas @mateoatr @sbomer

@vitek-karas
Copy link
Member

There's a somewhat detailed analysis of what's going on here: dotnet/sdk#14261.

The first issue (Sytem.Runtime) there is basically a need to add annotation to WPF code (or better change the pattern so that trimmer can recognize it).

The second one (System.Runtime.Extensions) is C++/CLI assembly problem which trimmer has trouble with. See for example #676. There's work being done on this right now.

The last one is probably also C++/CLI, but it's unclear yet.

@danmoseley
Copy link
Member

For the first one, @Symbai I am not are of plans for .NET 6 to add linker annotations to the WPF codebase (of course, you can ask that team who can say for sure). So that part may not get fixed - unless perhaps you are interested in contributing to that work.

@ThomasGoulet73
Copy link

This issue dotnet/wpf#3811 might be related, though I don't think the WPF has confirmed when or if they will do it. Someone from the WPF team self-assigned this issue so maybe they plan on doing it.

@vitek-karas
Copy link
Member

In .NET 6 we added explicit warning that trimming WPF apps is not supported (as described in the above discussion). I know it's not a solution to this issue, but it should at least set the right expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants