【问题标题】:WPF C# Check if needed files exist on app startupWPF C#检查应用程序启动时是否存在所需文件
【发布时间】:2019-01-29 15:29:32
【问题描述】:

我想在第一个应用程序窗口启动之前检查 .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.CheckLibrarys() 在 myapp.App..ctor() 在 myapp.App.Main()

这真的是某种 .Net Framework 玩笑吗?我在这里缺少什么?

编辑 1: 即使使用 OnStartup 覆盖也是同样的情况

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

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

【问题讨论】:

  • 您可以覆盖应用程序类的 OnStartup 方法,然后在那里使用您的逻辑。如果需要,我可以提供一个例子
  • 如果项目中引用了dll,则不能丢失,否则无法解析项目引用。如果您从项目引用中删除它并在运行时简单地加载它,那么您应该不会遇到这个问题。
  • 是的 mylib.dll 被引用了,所以我需要做其他事情来检查它们吗?
  • 您是否使用调试器单步执行了代码?异常发生在哪一行? MyDLL.dll 中定义的 IsResourceExist 方法是否偶然?

标签: c# wpf startup


【解决方案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 等是否告诉用户并退出来完全更改输出。

【讨论】:

  • 它抛出:System.Windows.Threading.DispatcherUnhandledExecptionEventArgs 和 System.UnhandledExceptionEventArgs
  • 我已经更新了答案以包含您的原始示例代码。
  • 删除 mylib.dll 文件只是应用程序正常启动而不会抛出任何错误
  • 是的,如果您实际上没有在任何地方使用库中的类,就会发生这种情况。在 WPF 应用程序的某处从库中实例化一个类,您将看到所描述的行为。
【解决方案2】:

您可以覆盖App.xamlOnStartup 方法。在此您可以添加您的自定义逻辑。

也许异常来自其他地方。您可以添加一个全局异常处理程序,并且可以查看它来自哪里。

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

【讨论】:

  • 我在事件查看器中添加了相同的方法,但没有工作抛出:System.IO.FileNotFoundException 但没有显示我丢失文件的消息框。
  • @Joel2 而不是 mylib.dll 尝试检查其他文件。
  • @Joel2 添加异常处理程序并查看异常的StackTrace
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-16
  • 2011-07-26
相关资源
最近更新 更多