0

I want to check if .dll, .png and .exe files exist before first app windows launches, but problem is I cant no matter how I try it just throws error in event viewer, instead my message.

My IsResourceExist Method:

private static bool IsResourceExist(string fileName)
{
            var process = Process.GetCurrentProcess();
            string path = process.MainModule.FileName.Replace("\\" + process.ProcessName + ".exe", "");
            try
            {
                if (!File.Exists(Path.Combine(path, fileName)))
                {
                    MessageBox.Show("Unable to load " + fileName + " library\nReinstall application and try again", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

Simple method nothing fancy, in normal situation(when file actually exist works fine)

private static bool CheckLibrarys()
        {
            if (!IsResourceExist("MyLib.dll")) return false;
            //Other resources checking same way
            return true;
        }

This method checks all apps needed resources, also works on normal situation(when all files exist)

This I think very first code line called by app, works when files exist

public App()
        {
            if (!CheckLibrarys()) Environment.Exit(0);
        }

When I delete MyLib.dll file in event viewer it throws:

Description: The process was terminated due to an unhandled exception. Exception Info: System.IO.FileNotFoundException at myapp.App.CheckLibrarys() at myapp.App..ctor() at myapp.App.Main()

Like for real is this somekind of .Net Framework joke? What I'm missing here?

EDIT 1: Same situation even with OnStartup override

protected override void OnStartup(StartupEventArgs e)
{      
     if (!CheckLibrarys()) Environment.Exit(0);
     base.OnStartup(e);
 }

EDIT 2 extending @bic answer and still app does not launch and does not throw any error that mylib is misssing

 private static bool CheckLibrarys()
        {
            if (!IsResourceExist("MyLib.dll")) { return false; }
            else
            {
                if (!MyLib.Init.ReturnOnlyTrue())
                {
                    MessageBox.Show("Wrong loaded library, reinstall application and try again", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }
            }
            //Other resources checking same way
            return true;
        }

In my MyLib Init class ReturnOnlyTrue() method look like this:

public static bool ReturnOnlyTrue()
        {
            return true;
        }
Joel2
  • 153
  • 2
  • 12
  • 1
    you can override OnStartup method of the app class, then use your logic there. I can provide an example, if it's needed – Sergey Anisimov Jan 29 '19 at 15:31
  • If the dll is referenced in the project then it cannot be missing otherwise the project references cannot be resolved. If you remove it from the project references and simply load it at runtime then you shouldnt have this problem. – bic Jan 29 '19 at 15:37
  • 1
    Possible duplicate of [Getting the application's directory from a WPF application](https://stackoverflow.com/questions/938421/getting-the-applications-directory-from-a-wpf-application) – Sinatr Jan 29 '19 at 15:38
  • Yes mylib.dll is referenced, so do I need todo something else to check them? – Joel2 Jan 29 '19 at 15:40
  • Have you stepped through the code with the debugger? What line does the exception occur at? Is the IsResourceExist method defined in MyDLL.dll by anychance? – PaulF Jan 29 '19 at 15:56
  • @PaulF No mylib.dll does not have IsResourceExist, IsResourceExist is unique and only App has it – Joel2 Jan 29 '19 at 16:00
  • OK - so back to my other questions - exactly what line causes the exception? – PaulF Jan 29 '19 at 16:02
  • If catching FileNotFoundException it throws on this line: if (!CheckLibrarys()) – Joel2 Jan 29 '19 at 16:06
  • Your own code is not the problem. The .NET runtime cannot resolve the library references defined in the exe. – bic Jan 29 '19 at 16:13
  • Have you tried stepping into the method - or does the exception occur at that line. – PaulF Jan 29 '19 at 16:15
  • @PaulF: The exception is coming from the framework and is not in the OPs code. Also, you cannot debug this situation because Visual Studio simply won't start the project because of missing references. – bic Jan 29 '19 at 16:25
  • @bic:I have just created a WPF application that references & uses a library (class instantiated & method called) - I have added the OPs code exactly as it is above without changes. I am able to run the application with or without the library in the application folder - with the dll obviously works OK, without the dll does not throw an exception but displays the expected message box & terminates correctly. – PaulF Jan 29 '19 at 16:31
  • @PaulF. Sorry, misread you comment. This is not the behaviour I've observed. – bic Jan 29 '19 at 16:33
  • See the edit - I clarified that when I said I used the library that I created a class instance & called a method from it. – PaulF Jan 29 '19 at 16:34
  • Does the class and method actually do anything? I've instantiated Class1 from my library and set it as the DataContext for MainWindow. – bic Jan 29 '19 at 16:36
  • @bic I updated my message with using test methods from my library but app does not launch and does not throw any error – Joel2 Jan 29 '19 at 16:37
  • Exactly. You should now see the FileNotFound exception in the event viewer if you dont have any error handling as shown in my answer. – bic Jan 29 '19 at 16:39
  • my event viewer is clear no errors that FileIsNotFoundException – Joel2 Jan 29 '19 at 16:40
  • Ok What mixing @bic method fhnaser methods finaly there some result, now it fails on if(!IsResourceExist("mylib.dll) else where I checking if existing library is correct and has needed class – Joel2 Jan 29 '19 at 16:51
  • @Joel2: Ok, I've updated my answer. – bic Jan 29 '19 at 16:53
  • @bic it wasnt my full answer accidently pressed enter, your methods is ok and i mixed with fhnaseer methods by adding CheckLibrarys in Onstartup, now one more thing to solve and thread can be closed, how to check if library has specified class/method? – Joel2 Jan 29 '19 at 16:56
  • @Joel2: That would be a separate Q&A in itself. What you're looking for is Reflection. See here: https://stackoverflow.com/questions/1315665/c-list-all-classes-in-assembly – bic Jan 29 '19 at 16:58

2 Answers2

1

If the dll is referenced in the project then it cannot be missing otherwise the project references cannot be resolved. If you remove it from the project references and simply load it at runtime then you shouldnt have this problem.

Here is a nice description of how the runtime resolves references. This is ultimately where the FileNotFound exception is coming from. https://learn.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies

In order for you to capture the error when the application starts you can add error handling as follows.

namespace SO_Wpf
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Windows;
    using System.Windows.Threading;

    public partial class App : Application
    {
        public App()
        {
            Current.DispatcherUnhandledException += this.AppDispatcherUnhandledException;
            AppDomain.CurrentDomain.UnhandledException += this.AppDomainUnhandledException;
        }

        private void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            if (e.Exception.GetType() == typeof(FileNotFoundException))
            {
                if (!CheckLibrarys())
                {
                    Current.Shutdown();
                }
            }
            else
            {
                MessageBox.Show(e.Exception.Message);
            }
        }

        private void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject.GetType() == typeof(FileNotFoundException))
            {
                if (!CheckLibrarys())
                {
                    Current.Shutdown();
                }
            }
            else
            {
                MessageBox.Show(e.ExceptionObject.ToString());
            }
        }

        private static bool CheckLibrarys()
        {
            if (!IsResourceExist("MyLib.dll"))
            {
                return false;
            }

            //Other resources checking same way
            return true;
        }

        private static bool IsResourceExist(string fileName)
        {
            var process = Process.GetCurrentProcess();
            var path = process.MainModule.FileName.Replace("\\" + process.ProcessName + ".exe", "");
            try
            {
                if (!File.Exists(Path.Combine(path, fileName)))
                {
                    MessageBox.Show("Unable to load " + fileName + " library\nReinstall application and try again", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

e.Exception.Message will give you the message or you can change the output altogether by checking the error and if its FileNotFoundException etc. tell the user and exit.

bic
  • 2,201
  • 26
  • 27
  • It throws: System.Windows.Threading.DispatcherUnhandledExecptionEventArgs and System.UnhandledExceptionEventArgs – Joel2 Jan 29 '19 at 15:57
  • Ive updated the answer to include your original sample code. – bic Jan 29 '19 at 16:06
  • Deleting mylib.dll file just app starts normally without throwing any error – Joel2 Jan 29 '19 at 16:19
  • Yes, that will happen if you are not actually using the classes in the library anywhere. Instantiate a class from your library somewhere in your WPF app and you will see the behaviour described. – bic Jan 29 '19 at 16:21
-2

You can override OnStartup method of App.xaml. In this you can add your custom logic.

Maybe exception is coming form somewhere else. You can add a global exception handler and can see from where it is coming form.

public partial class App : Application
{
    public App()
    {
        DispatcherUnhandledException += App_DispatcherUnhandledException;
    }

    private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        e.Handled = true;
        MessageBox.Show(e.Exception.Message);
        Environment.Exit(0);
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        if (!SomeCondition)
            Application.Current.Shutdown();
    }
}
fhnaseer
  • 7,159
  • 16
  • 60
  • 112