简体   繁体   中英

XamlParseException when referenced dll not found on startup

I have referenced a dll in my project. When I start my WPF application and the dll is not present in the same folder, I get an unhandled XamlParseException in Visual Studio. When I run in Release mode the app just crashes.

I tried handling that Exception before App startup using the code below. Unfortunately the exception's message says nothing about the dll that was not found, but has this message:

Cannot create instance of 'MainWindow' defined in assembly 'App.Demo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation.  Error in markup file 'MainWindow.xaml' Line 1 Position 9.

The inner exception however has this content:

InnerException: System.Reflection.TargetInvocationException
       Message=Exception has been thrown by the target of an invocation.
       Source=mscorlib
       StackTrace:
            at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
            at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
            at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
            at System.Activator.CreateInstance(Type type, Boolean nonPublic)
            at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
       InnerException: System.IO.FileNotFoundException
            Message=Could not load file or assembly 'MyLibrary, Version=1.0.9999.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
            Source=App.Demo
            FileName=MyLibrary, Version=1.0.9999.0, Culture=neutral, PublicKeyToken=null
            FusionLog==== Pre-bind state information ===

Is there a common approach to handling these cases where a referenced library is not found?

public partial class App : Application
    {

        protected override void OnStartup(StartupEventArgs e)
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledException);

        }

        void UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = (Exception) e.ExceptionObject;
            System.Windows.MessageBox.Show(ex.Message);
            Application.Current.Shutdown();
        }


    }

Whats also strange: Although I call Application.Current.Shutdown , the Exception is thrown again after that resulting in the same crash of my application.

EDIT: Added the code for MainWindow.xaml and App.xaml

App.xaml:

<Application x:Class="Demo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>

MainWindow.xaml:

<Window x:Class="Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="My Application" Height="768" Width="1024" MaxWidth="1024" MinWidth="1024" MinHeight="768" MaxHeight="768" Background="#004B93">

The problem is that the XAML parser doesn't actually cause a reference to the referenced assembly, so the referenced assembly gets removed when you build. The build chain does this to prevent unused assemblies from being copied (eg System.Core which is referenced by default). Just add a reference to your assembly in your code and it should be good to go.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/7f255570-dd53-41f8-b8c4-a160ba325c90/reference-not-loaded-into-assembly-when-only-using-xaml-for-the-referenced-code-bug?forum=wpf

Any reference in code will work, but I like this one.

using System;

namespace MyReferencedAssembly
{
    /// <summary>
    /// Use to force an assembly reference
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.Assembly)]
    public class AssemblyReferenceAttribute : Attribute
    {
    }
}

In your app's AssemblyInfo.cs, just add a reference attribute:

[assembly: MyReferencedAssembly.AssemblyReference]

I'm not sure of this, but I think we'd need to see the App.xaml and MainWindow.xaml to get what's wrong. Perhaps you're creating a static resource in either of these, with the resource type defined in the DLL. The xaml parser wouldn't find the assembly and fail to create an instance of this object. Also are you using StartupUri and Startup at the same time?

When I start my WPF application and the dll is not present in the same folder

The dll you've referenced needs to be accessible by your application - by default it will look in the same folder as the executable. If it can't find the dll, how could it load the stuff you use from the libraries?

In Visual Studio, under the properties for the reference make sure that "Copy Local" is set to true. Afterwards, for good measure run Build -> Clean Solution, then Build -> Rebuild Solution. The MyLibrary.dll should now be in the release folder and you shouldn't get the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM