WPF C#检查应用启动时是否存在所需的文件

时间:2019-01-29 15:29:33

标签: c# wpf startup

我想在启动第一个应用程序窗口之前检查.dll,.png和.exe文件是否存在,但是问题是,无论如何尝试,我都无法在事件查看器中引发错误,而是我的消息。

我的IsResourceExist方法:

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

简单的方法没什么花哨的,在正常情况下(当文件实际存在时效果很好)

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

此方法检查所有应用程序所需的资源,也可以在正常情况下(当所有文件都存在时)工作

我认为这是应用调用的第一行代码,当文件存在时有效

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

当我在事件查看器中删除MyLib.dll文件时,它会抛出:

  

说明:由于未处理的异常,进程已终止。   异常信息:System.IO.FileNotFoundException在   位于myapp.App..ctor()处的myapp.App.CheckLibrarys()   myapp.App.Main()

这真像.Net Framework的笑话吗?我在这里想念什么?

编辑1: 即使使用OnStartup覆盖,情况相同

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

编辑2扩展了@bic答案,仍然没有启动应用程序,不会抛出mylib遗漏的任何错误

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

在MyLib Init类的ReturnOnlyTrue()方法中,如下所示:

public static bool ReturnOnlyTrue()
        {
            return true;
        }

2 个答案:

答案 0 :(得分:1)

如果在项目中引用了dll,则它不会丢失,否则无法解析项目引用。如果将其从项目引用中删除并仅在运行时加载它,那么您就不会遇到这个问题。

这里很好地描述了运行时如何解析引用。最终这就是FileNotFound异常的来源。 https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies

为了让您在应用程序启动时捕获错误,可以添加如下的错误处理。

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将给您消息,或者您可以通过检查错误以及它的FileNotFoundException等是否通知用户并退出来完全更改输出。

答案 1 :(得分:-2)

您可以覆盖OnStartup的{​​{1}}方法。您可以在其中添加自定义逻辑。

也许其他地方即将出现例外情况。您可以添加一个全局异常处理程序,并可以从哪里看到表单。

App.xaml