Search This Blog

Monday, March 10, 2008

EventLog Problems in C# in 64-bit .NET Framework 2.0

While developing a web service in C# I decided to have it write its audit/error messages out to a custom event log -- writing them out to the Application Event log seemed rude since this wasn't my server and the client was already having all sorts of other apps write to the App log.

Besides, I thought it would make life easier for me since all my messages would be in their own separate-but-equal log. An eventlog of one's own, so to speak.

By and large the eventlog documentation from Microsoft is pretty good with one small exception that's cost me about 90 minutes to figure out: the EventSource and EventLog parameters need to be the same string, at least with the 64-bit implementation of .NET Framework 2.0.

The problem arose when installing the service on the client's server. The install code performed the customary check of the EventLog service to see if the event source information was already registered and, if not, registered it:

string SSource = "Exchange Provisioning Service";
string SLog = "ExchProvLog";
EventSourceCreationData esc1 = new EventSourceCreationData("Exchange Provisioning Service", "ExchProvLog");
if (!EventLog.SourceExists(sSource))

EventLog.CreateEventSource(esc1);

But subsequent calls to the event log would throw an error message:

EventLog.Write("Exchange Provisioning Service", "Service VWoolf1 started successfully", EventLogEntryType.SuccessAudit,234);

resulted in:

"The local computer may not have the necessary registry information or DLL files to display messages from a remote computer"

After the 90 minutes spent Googling the best link was a Dr. Dobb's Journal article from 2004 which provided the background to solving the problem (http://www.ddj.com/windows/184405714). The article doesn't address this particular problem but it showed where to start.

When registering an EventSource with the EventLog service the service creates a key under HKLM\SYSTEM\CurrentControlSet\Services\EventLog for the new EventLog. Under this entry is an entry for the new Event Source. This is evidently where the action is -- in this registry key is an "EventMessageLog" pointer which points to the DLL with the library of error messages which the log uses for this type of event source.

If the Event Source and Event Log are different, unfortunately, it puts in two entries under HKLM\SYSTEM\CurrentControlSet\Services\EventLog\: one with the new Event Source, the other with the new Event Log. This it doesn't like, and it throws that message above.

I guess you could just use the registry editor to snip out the one of these two SourceName entries you don't like but, since I was writing this for a user install, I didn't want to screw with that and felt that using a one-name-for-both entities solution is good enough for now. It works, and that has a lot going for it.

One additional note:

When you're writing the de-install part of this user install package, when you want to completely remove your program and the custom event log you created from the user's machine, I've found that just deleting the event log:

EventLog.Delete(Logname);

is sufficient. Don't screw with removing the event source and then the event log, it just seems to cloud the issue and throw exceptions.

//EventLog.DeleteEventSource(EventSource); // don't bother with this
EventLog.Delete(Logname);

No comments: