dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
6.84k stars 1.13k forks source link

Calling a wpf lib with reflection raised TargetInvocationException #9039

Open NeverMorewd opened 3 weeks ago

NeverMorewd commented 3 weeks ago

Description

.NET8 visual studio 2022

Reproduction Steps

  1. Create a wpf custom control lib or user control lib
  2. Add nuget Microsoft.Xaml.Behaviors or any nuget which can be referenced at xaml else
  3. Add a page or control as below
    <Page
    x:Class="View"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Grid>
        <TreeView ItemsSource="{Binding ElementsView}">
            <behaviors:Interaction.Triggers>
                <behaviors:EventTrigger EventName="SelectionChanged">
                    <behaviors:InvokeCommandAction Command="{Binding LoadElementDetailCommand}" />
                </behaviors:EventTrigger>
                <behaviors:EventTrigger EventName="TreeViewItem.Expanded">
                    <behaviors:InvokeCommandAction Command="{Binding LoadChildrenCommand}"/>
                </behaviors:EventTrigger>
            </behaviors:Interaction.Triggers>
        </TreeView>
    </Grid>
    </Page>
  4. Compile project with output View.dll
  5. Assembly.LoadFrom("View.dll") and create instance of “View” in a Console project.
  6. Run or debug Console project
  7. Raise exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Windows.Markup.XamlParseException: Could not load file or assembly 'Microsoft.Xaml.Behaviors, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. 系统找不到指定的文件。 ---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Xaml.Behaviors, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. 系统找不到指定的文件。 File name: 'Microsoft.Xaml.Behaviors, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext, RuntimeAssembly requestingAssembly, Boolean throwOnFileNotFound) at System.Reflection.Assembly.Load(AssemblyName assemblyRef) at System.Windows.Baml2006.Baml2006SchemaContext.ResolveAssembly(BamlAssembly bamlAssembly) at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlTypeToType(BamlType bamlType) at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlType(BamlType bamlType, Int16 typeId) at System.Windows.Baml2006.Baml2006SchemaContext.GetXamlType(Int16 typeId) at System.Windows.Baml2006.Baml2006SchemaContext.GetProperty(Int16 propertyId, XamlType parentType) at System.Windows.Baml2006.Baml2006Reader.Process_PropertyArrayStart() at System.Windows.Baml2006.Baml2006Reader.Process_OneBamlRecord() at System.Windows.Baml2006.Baml2006Reader.Process_BamlRecords() at System.Windows.Baml2006.Baml2006Reader.Read() at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector) at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) --- 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.LoadComponent(Object component, Uri resourceLocator)

source: https://github.com/dotnet/wpf/blob/148547d6d5956fca930028582ddc8bbe2058bfe9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/Baml2006SchemaContext.cs#L24

Expected behavior

Run without exceptions

Actual behavior

Throw TargetInvocationException

Regression?

No response

Known Workarounds

Adding a usage of Microsoft.Xaml.Behaviors in csharp code can avoid this issue.

using Microsoft.Xaml.Behaviors.Core;

namespace View
{
    public class HostedService : IAppHostedService
    {
        public HostedServicer()
        {
            // Any reference  of Microsoft.Xaml.Behaviors will work
            ConditionBehavior conditionBehavior = new ConditionBehavior();
        }
    }
}

It seems that there are some differences between the mechanism of baml assembly loading and csharp

Impact

No response

Configuration

No response

Other information

No response

miloush commented 3 weeks ago

please provide a repro project

NeverMorewd commented 3 weeks ago

please provide a repro project

https://github.com/NeverMorewd/Lemon.Automation

  1. gitclone
  2. build solution
  3. the launchsettings of Lemon.Automation.App should be noticed : "-a AppUITracker AppUIProvider -b false"
  4. run with/without debug Lemon.Automation.App
  5. everything will go well

However

  1. Locate to line 27 of https://github.com/NeverMorewd/Lemon.Automation/blob/main/src/Lemon.Automation.App.UITracker/HostedService.cs
  2. delete this line.
  3. rebuild Lemon.Automation.App.UITracker
  4. run with/without debug Lemon.Automation.App you will get this issue.