Search code examples
c#wpfstartup

WPF C# Check if needed files exist on app startup


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;
        }

Solution

  • 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.