抛出异常时,C# 应用程序静默失败

C# Application fails silently when exception is thrown

我制作了一个在启动时抛出异常的小型 winforms 应用程序:

static void Main()
{
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  throw new Exception("lol");
  Application.Run(new Form1());
}

当我从调试器 运行 执行此操作时,如我所料抛出异常。如果我浏览到 bin 目录中的可执行文件,如果从资源管理器浏览到 运行,则该应用程序会静默失败,甚至不会显示 'This application has crashed dialog'.

我确实在事件查看器中记录了异常:

Application: WindowsFormsApplication1.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Exception
   at WindowsFormsApplication1.Program.Main()

但这并不是很大的帮助!

很多应用程序都会出现这种情况,我觉得我有一些系统范围的设置抑制了这个系统对话框,但我不知道它可能是什么!任何指导将不胜感激。

据我了解,WinForms 应用程序仅在

Application.Run(new Form1());

通话成功。它没有控制台输出,它会尝试通过 WinForms UI 告诉你一切。但目前还没有。

如果您希望应用程序显示任何内容,您必须确保消息循环已启动。因此,如果您想在应用程序启动时立即抛出异常,请重写窗体的 OnLoad 方法并在那里抛出异常。 (我将代码从 Program.cs 移到了表单的代​​码隐藏)

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            throw new ApplicationException("ASDF");
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //AllocConsole();
            //Console.WriteLine("BOOO");
            //throw new ApplicationException("BOOOO");
            Application.Run(new Form1());
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole();

    }
}

这应该会向您显示 "nice" 异常 window。

或者写一个控制台应用程序。 :)

如果必须,可以尝试分配一个控制台输出:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            AllocConsole();
            Console.WriteLine("BOOO");
            throw new ApplicationException("BOOOO");
            Application.Run(new Form1());
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole();
    }
}

但恕我直言,让应用程序启动,然后在它应该使用的 UI 上处理问题,将是更简洁的方法。

尝试处理 appdomain 未处理的异常事件。

  public static void Main()
  {
   AppDomain currentDomain = AppDomain.CurrentDomain;
   currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
  }

  static void MyHandler(object sender, UnhandledExceptionEventArgs args) 
  {
   Exception e = (Exception) args.ExceptionObject;
   Console.WriteLine("MyHandler caught : " + e.Message);
   Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
  }

https://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception(v=vs.110).aspx