在Windows服务中处理AppDomain.CurrentDomain.UnhandledException

时间:2014-04-16 15:58:34

标签: c# exception-handling unhandled-exception

我有窗口服务,它充当同步软件。我想在我的服务上添加无法异常的日志记录,因此我修改了program.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 { }
    }
}

然后在我的Service.cs文件中,在OnStart方法中,我添加了throw new Exception("test");,以查看是否按预期将无法处理的异常记录到文件中。

当我启动我的服务时,它会立即停止 ;但它似乎并没有将异常记录到指定的文件中。

知道我在这里做错了吗?提前感谢您的帮助。

在你提问之前,我的服务运行为Local Service,我的服务.exe运行的目录(c:\ mysync)已经在安全选项卡中添加了Local Service并完整阅读/写访问权。

2 个答案:

答案 0 :(得分:4)

在try-catch块内的Service基类中调用OnStart。如果在此阶段发生异常,它会捕获它并仅将结果设置为状态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中找到一条记录,但是您无法将其作为无法域的异常捕获,因为没有此类异常。

答案 1 :(得分:1)

   using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))

不使用文件的完整路径名(例如c:\ foo \ bar.log)永远不是真的坏主意。特别是在服务中,您几乎无法控制服务的默认目录。因为它是由服务控制管理器启动的,而不是由用户从命令提示符或桌面快捷方式启动的。

你只是看错了文件的几率很高。真正的一个可能最终被写入c:\ windows \ system32(或syswow64)。操作系统目录通常是写保护但对服务不起作用,它们使用高权限帐户运行,因此可以在任何地方乱丢硬盘。

始终使用完整路径名称。强烈建议使用EventLog。