抛出异常时,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
我制作了一个在启动时抛出异常的小型 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