当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - 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.

网友答案:

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.

网友答案:
   using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))

It is forever a really bad idea to not use full path names for files (like c:\foo\bar.log). Especially in a service, you have very little control over the default directory for your service. Because it is started by the service control manager, not by the user from the command prompt or a desktop shortcut.

So high odds that you are just looking at the wrong file. The real one probably ended up being written to c:\windows\system32 (or syswow64). The operating system directories are normally write protected but that doesn't work for a service, they run with a highly privileged account so can litter the hard drive anywhere.

Always use full path names. Using the EventLog instead is highly recommended.

分享给朋友:
您可能感兴趣的文章:
随机阅读: