Search code examples
c#powershelleventlog-source

Creating previously deleted source in different event log doesnt work


I have been fighting with the Windows Event log for lots of hours with inconsistent behaviour during test of the log4net EventLogAppender and I realized, that the log4net code worked, but my windows event log was the one being unreasonable.

System

  • OS: Windows 8.1
  • C#: .Net 4.5, built to x64

Creating the error case

  • C#: Create Source1 in TestLog1
  • C#: Write to the log (Works)
  • Powershell: Removing the log using powershell
  • C# Create Source1 in TestLog2 (Different log)
  • C# Write to the log <= This shows no log entries in TestLog2!

I have made a complete step-by-step guide to recreate the problem:

1: Create a new source in a new log and write to it

Code executed:

EventLog.CreateEventSource(source: "TestSource1", logName: "TestLog1");
EventLog myLog = new EventLog();
myLog.Source = "TestSource1";
myLog.WriteEntry("This is a message");

List logs using powershell-command:

Get-EventLog -LogName *

This will correctly list all logs, including TestLog1 containing 1 log entry. I can also get the log entries by using this powershell command:

GetEventLog -LogName "TestLog1"

This shows me the single log message in the log.

2: Delete the event log using powershell

Powershell command:

Remove-EventLog -LogName "TestLog1"

Listing all logs now shows, that the log has actually been deleted. Powershell command again:

Get-EventLog -LogName *

3: Create the source again, but in another log this time

Code executed:

EventLog.CreateEventSource(source: "TestSource1", logName: "TestLog2"); // New log name
EventLog myLog = new EventLog();
myLog.Source = "TestSource1";
myLog.WriteEntry("This is a message");

Result:

  • The log appears in powershell when listing all logs
  • The log does not contain any entry
  • Using Get-EventLog "TestLog2" throws and exception even though it appears in the log-list
  • Deleting the log in powershell using remove-eventlog -logName "TestLog2" somehow still works.

It seems that in some cases, the logs seems to exist, but in others it doesnt.

A: Is this a known bug or what is wrong with my scenario?

B: How can I clean up my existing mess if sources somehow still exist pointing at the old log? (If thats the case, that is)

EDIT: I even tried the following C# code to delete the source first and then the log, but the result is the same:

var source = "TestSource6";
var logName1 = "Testlog5";
var logName2 = "Testlog6";

EventLog.CreateEventSource(source: source, logName: logName1);

new EventLog() { Source = source }.WriteEntry("This is a message in log " + logName1);

EventLog.DeleteEventSource(source:source);
EventLog.Delete(logName:logName1);

EventLog.CreateEventSource(source: source, logName: logName2);
new EventLog() { Source = source }.WriteEntry("This is a message" + logName2);

Solution

  • Unfortunately you can't re-register an event source "back to back". It's one of the (many) reasons installers often ask to restart the computer.

    From MSDN:

    If a source has already been mapped to a log and you remap it to a new log, you must restart the computer for the changes to take effect.

    EventLog.CreateEventSource Method (String, String)

    For fixing the issue, I would recommend not deleting the event source unless the product is uninstalled. Just stop using Log1 and start using Log2, without deleting and recreating. When you go to use any log, you could use something similar to this:

    if (!EventLog.SourceExists(source, log))
    {
        EventLog.CreateSource(source, log)
    }
    

    And simply leave the source where it is, until you uninstall the product. If you're using InstallShield, it should automatically detect a restart is required and ask the user to do so.