C# 在windows服务中处理AppDomain.CurrentDomain.UnhandledException
我有一个窗口服务作为一个同步软件。我想在我的服务中添加未受影响的异常日志记录,因此我修改了我的C# 在windows服务中处理AppDomain.CurrentDomain.UnhandledException,c#,exception-handling,unhandled-exception,C#,Exception Handling,Unhandled Exception,我有一个窗口服务作为一个同步软件。我想在我的服务中添加未受影响的异常日志记录,因此我修改了我的程序.cs,如下所示: static class Program { /// <summary> /// The main entry point for the application. /// </summary> [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermis
程序.cs
,如下所示:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
static void Main()
{
// Register Unhandled Exception Handler
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
// Run Service
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service()
};
ServiceBase.Run(ServicesToRun);
}
static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
// Get Exception
Exception ex = (Exception)args.ExceptionObject;
// Generate Error
string ErrorMessage = String.Format(
"Error: {0}\r\n" +
"Runtime Terminating: {1}\r\n----- ----- ----- ----- ----- -----\r\n\r\n" +
"{2}\r\n\r\n####################################\r\n",
ex.Message,
args.IsTerminating,
ex.StackTrace.Trim());
// Write Error To File
try
{
using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))
sw.WriteLine(errorMessage);
}
catch { }
}
}
静态类程序
{
///
///应用程序的主要入口点。
///
[SecurityPermission(SecurityAction.Demand,Flags=SecurityPermissionFlag.ControlAppDomain)]
静态void Main()
{
//注册未处理的异常处理程序
AppDomain.CurrentDomain.UnhandledException+=
新的未处理的ExceptionEventHandler(未处理的ExceptionHandler);
//运行服务
ServiceBase[]ServicesToRun;
ServicesToRun=新的ServiceBase[]
{
新服务()
};
ServiceBase.Run(ServicesToRun);
}
静态void UnhandledExceptionHandler(对象发送方,UnhandledExceptionEventArgs参数)
{
//破例
异常ex=(异常)args.ExceptionObject;
//产生错误
string ErrorMessage=string.Format(
“错误:{0}\r\n”+
“运行时终止:{1}\r\n-------------------------\r\n\r\n”+
[3 3 7 7 7 7 7 7 7 7 7 7 7 7 3 3 3 3 3 3\\\r\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#\r\n“,
例如,信息,
args.IsTerminating,
例如StackTrace.Trim());
//文件写入错误
尝试
{
使用(StreamWriter sw=File.AppendText(“UnhandledExceptions.log”))
软件写入线(错误信息);
}
捕获{}
}
}
然后在我的Service.cs
文件中,在OnStart
方法中,我添加了一个抛出新异常(“test”)
查看是否按预期将未处理的异常记录到文件中
当我开始服务时,它会像预期的那样立即停止;但是,它似乎没有将异常记录到指定的文件中
知道我做错了什么吗?提前感谢您的帮助
在您询问之前,我的服务以
Local service
的形式运行,并且运行我的service.exe的目录(c:\mysync)已经在具有完全读/写访问权限的安全选项卡中添加了Local service
。OnStart在try-catch块内的服务基类中调用。如果在此阶段发生异常,它将捕获该异常并将其作为结果设置为状态1,并且不进一步抛出该异常:
string[] args = (string[]) state;
try
{
this.OnStart(args);
.....
}
catch (Exception ex)
{
this.WriteEventLogEntry(Res.GetString("StartFailed", new object[1]
{
(object) ((object) ex).ToString()
}), EventLogEntryType.Error);
this.status.currentState = 1;
}
因此,您可以在EventLogs中找到一条记录,但无法将其作为未经处理的域异常捕获,因为不存在此类异常
using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))
不使用文件的完整路径名(如c:\foo\bar.log)永远是一个非常糟糕的主意。特别是在服务中,您几乎无法控制服务的默认目录。因为它是由服务控制管理器启动的,而不是由用户从命令提示符或桌面快捷方式启动的
很有可能你只是看错了文件。真正的一个可能最终被写入c:\windows\system32(或syswow64)。操作系统目录通常是写保护的,但这不适用于服务,它们使用高度特权的帐户运行,因此可以在任何地方乱扔硬盘
始终使用完整路径名。强烈建议改用事件日志。服务框架最有可能捕获异常,因此它不会“未处理”,因此不会触发事件。您的
StreamWriter
实例是否肯定会在处理之前刷新其内容?请尝试使用文件.AppendAllText(string,string)
方法。感谢您的提示。由于框架捕获到异常,因此未在任何地方编写该方法,请参阅上面的代码。这在很大程度上取决于代码出现的位置。如果它在一个ServiceBase方法重写中,则可以,但在其他任何地方都不可以。这是很可能的情况。它在ServiceBase代码、方法中:private void ServiceQueuedMainCallback(对象状态)。不幸的是,没有办法重写它。当然,这是调用OnStart、OnStop、OnPause等的内部方法。您必须在自己的类中重写这些方法。OnStart()通常启动线程或计时器,OnStop()会再次停止它。这样一个线程中的任何异常都不会自动被记录下来,当然也没有像服务控制器回调中那样的支持。没有发生“未经处理的”异常。正如你所详述的;异常自动记录在事件日志中。谢谢