0

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">

H.B.
  • 166,899
  • 29
  • 327
  • 400
tzippy
  • 6,458
  • 30
  • 82
  • 151

3 Answers3

1

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 (e.g. 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]
0

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?

FatalJamòn
  • 386
  • 2
  • 10
  • I added both the xaml files – tzippy Jul 21 '16 at 13:43
  • OK, so it didn't help at all... So tell me, it only crashes in Release mode and not Debug mode? Do you try Release mode from Visual Studio CTRL+F5 key or did you create some setup and launch it from there? Perhaps the setup doesn't copy the DLL? I'm as confused as other replier... – FatalJamòn Jul 21 '16 at 14:02
0

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.

plast1k
  • 793
  • 8
  • 15
  • "Copy Local" is set to true. I'm actually referring to the release case when the application is deployed and the dll is not present for some reason. before using any of the functionality from the library it should check whether the dll is present. This case should be handable right? – tzippy Jul 21 '16 at 13:41
  • It's still not clear on if it the assembly being missing is a possible, expected state of your application. If it is an expected possibility, then you'll most likely need to do more than just handing the exception, and will need to start looking into dynamically loading assemblies. See here: http://stackoverflow.com/questions/5198367/how-to-try-and-catch-assembly-not-found. Also look into MEF – plast1k Jul 21 '16 at 13:56
  • This captures my issue quite well. I'm looking into the AssemblyResolve event now. Thanks! – tzippy Jul 21 '16 at 14:03