Search code examples
c#exceptionunhandled-exception

Handling AppDomain.CurrentDomain.UnhandledException in windows service


I have window service which acts as a sync software. I want to add unhanded exception logging on my service, so I modified my program.cs like this:

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 { }
    }
}

Then on my Service.cs file, in the OnStart method, I added a throw new Exception("test"); to see if unhanded exceptions are being logged to file as expected.

When I start my service, it stops immediately as expected; however it doesn't seem to be logging the exception to the specified file.

Any idea what I am doing wrong here? Thanks in advance for any help.

Before you ask, my service runs as Local Service and the directory where my service .exe runs from (c:\mysync) already has Local Service added in the security tab with full read/write access.


Solution

  • OnStart is called in Service base class inside try-catch block. If an exception happens on this stage it catches it and just set a status 1 as a result and do not throw it further:

      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;
      }
    

    As a result you can find a record in EventLogs, but you can't catch it as an unhanded domain exception, as there is no such exception.