【问题标题】:WPF application immediately closes for userWPF 应用程序立即为用户关闭
【发布时间】:2019-11-12 15:06:24
【问题描述】:

我有一个为我工作的公司构建的 WPF 应用程序。整个事情在我的机器和分支网络中的其他机器上运行良好。

但是,我们总部的一位用户无法使用它。应用程序在启动时立即关闭。我尝试在任务管理器中监控它,它出现了,然后立即关闭。

所以,我决定在启动表单中放一些消息框,看看它失败的地方:

    public LoginWindow()
    {
        MessageBox.Show("CHECKING FOR UPDATES");
        var updated = Jmis.IsUpdated();
        MessageBox.Show("UPDATES CHECKED");
        if (updated)
        {
            MessageBox.Show("LOADING SETTINGS");
            Settings = FileManager.LoadSettings();
            MessageBox.Show("SETTINGS LOADED");
            this.DataContext = Settings;
            InitializeComponent();
            Password.Password = Settings.Password;
        }
        else
        {
            MessageBox.Show("A new version is available!", "Update", MessageBoxButton.OK, MessageBoxImage.Information);
            new UpdateWindow().Show();
            Close();
        }
        InitializeComponent();
    }

它显示CHECKING FOR UPDATES 消息,然后关闭。

同样,我在Jmis.IsUpdated() 方法中添加了一些消息框:

    public static bool IsUpdated()
    {
        try
        {
            MessageBox.Show("Sending request");
            var response = Http.GetAsync($"{JmisUri}/toasterNotification/version.php").Result;
            MessageBox.Show("Ensuring success");
            response.EnsureSuccessStatusCode();
            MessageBox.Show("Getting version string");
            var version = response.Content.ReadAsStringAsync().Result;
            MessageBox.Show("Checking version");
            return version == Assembly.GetExecutingAssembly().GetName().Version.ToString();
        } 
        catch(Exception ex)
        {
            return true;
        }
    }

我至少期待Sending request 出现。但它没有。我仍然得到CHECKING FOR UPDATES,但没有别的。

就好像根本没有调用该方法。

我真的被难住了。

有什么原因会发生这种情况吗?

编辑

查看事件日志后发现:

Application: JMIS Notifier.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
   at JMIS_Notifier.JMIS.Jmis..cctor()

Exception Info: System.TypeInitializationException
   at JMIS_Notifier.JMIS.Jmis.IsUpdated()
   at JMIS_Notifier.LoginWindow..ctor()

Exception Info: System.Windows.Markup.XamlParseException
   at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri)
   at System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean)
   at System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext)
   at System.Windows.Application.LoadComponent(System.Uri, Boolean)
   at System.Windows.Application.DoStartup()
   at System.Windows.Application.<.ctor>b__1_0(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
   at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
   at System.Windows.Application.RunDispatcher(System.Object)
   at System.Windows.Application.RunInternal(System.Windows.Window)
   at System.Windows.Application.Run(System.Windows.Window)
   at System.Windows.Application.Run()
   at JMIS_Notifier.App.Main()

有趣的是异常发生在JMIS_Notifier.JMIS.Jmis..cctor(),但它是一个静态类。

【问题讨论】:

  • 查看系统事件日志。那里应该有一条错误消息。
  • 你为什么在LoginWindow中打电话给InitializeComponent();?从表面上看,可能有很多事情是错误的。您是否正确地通过了Jmis.IsUpdated();
  • catch unhandled exceptions吗?远程调试器是一个更好的选择。
  • 此行为的最常见原因是无法加载引用的程序集,因为 a) 它未安装 b) 它依赖于未安装的其他 dll 或 c) 它需要操作系统是 64 位,但操作系统是 32 位,反之亦然
  • @NineBerry 我发布了一个答案,似乎已经为我们的一位用户解决了这个问题。我很快就会为其他用户测试它。

标签: c# wpf


【解决方案1】:

当我遇到这样的问题之前,通常是缺少库。在没有更多信息的情况下,我只能在这里猜测,但我猜测当您调用 IsUpdated 时,它正在从您的 using 语句中加载其他库。

可能存在预期安装的软件未安装在此人的计算机上。

您可以使用依赖遍历器http://www.dependencywalker.com/ 来查看您是否缺少库。

编辑

TypeInitializationException 只是告诉你类初始化失败。由于Jmis 是一个静态类,或者依赖于静态类,因此在调用IsUpdated 方法之前会调用静态构造函数和初始化程序,并且在Jmis 类的初始化中找不到文件。

因此,很可能没有安装与 Jmis 相关的东西,或者 Jmis 正在寻找的某些资源在发生故障的机器上不可用。

【讨论】:

  • 除了使用dependency walker外,当问题是加载托管程序集而不是本地dll时,您可以使用Fusion Logging来分析问题。
  • @Christopher 该应用程序没有给出这种异常的迹象,因此我很困惑。即使在您指出的方法中,我在捕获后返回 true,如果我放置显示 ex.Message 的消息框,它也永远不会显示。
  • @Christopher 它正在抛出一个异常,该异常现在包含在问题中,但它在 IsUpdated 被调用之前被抛出,所以他的 try catch 根本没有吞下它,因为它从来没有进入他的 try catch 块。
  • IIRC,当框架应用程序在没有附加调试器的情况下遇到异常时,框架本身会捕获它并将其显示在一个巨大的消息框中。框架本身是终极的后备暴露者。 |如果他只在事件日志中找到它,那么某些东西似乎令人难以置信 - 而不是让框架将异常细节推到用户面前。 |但是,是的,FileNotFound 通常是缺少库的指示符。 (同样,链接的例子是字面意思的情况)
  • 你是对的。我只需要安装我的应用程序所针对的 .NET Framework。这是我唯一能想到的,因为我使用Costura.Fody 将其他依赖项合并到可执行文件中。我只是觉得奇怪的是我没有收到任何迹象表明它缺少正确的框架。
【解决方案2】:

好的,所以我认为由于用户运行的是 Windows 8.1,并且我的程序集以 .NET Framework 4.7.2 为目标,因此我可能必须安装该版本的 .NET Framework。

所以我已经这样做了,它似乎已经解决了这个问题。

我只是觉得奇怪,通常应用程序会在您尝试打开它时告诉您需要某个 .NET Framework 版本。

也许这与我使用Costura.Fody 将依赖项合并到可执行文件中这一事实有关。

【讨论】:

    猜你喜欢
    • 2019-01-27
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2017-01-14
    • 2019-06-03
    • 1970-01-01
    相关资源
    最近更新 更多