views:

184

answers:

2

My following code fails with "...has already been registered as a source on the local computer" even though I'm doing checks first:

lock ( eventLock )
{
    string eventLog = Constants.EventLogPL;
    string eventSrc = Constants.EventSrcPL;

    if (!EventLog.Exists(eventLog))
    {
        if (!EventLog.SourceExists(eventSrc))
        {
            try
            {
                EventLog.CreateEventSource(eventSrc, eventLog);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
            }
        }
    }
}

I'd have thought my call to !EventLog.SourceExists would have been enough to prevent my error! I'm on 2010 .NET 4 and Windows 7 64 compiling to any CPU.

Edit: Updated code to get Constant's to locals to check they don't change, and use locking to make sure only one thread can test and create. Code still fails with the same error.

A: 
//0 for false, 1 for true.
private static int usingResource = 0;

if (!EventLog.SourceExists(Constants.EventSrcPL))
{
    //0 indicates that the method is not in use.
    if (0 == Interlocked.Exchange(ref usingResource, 1))
    {
        if (!EventLog.SourceExists(Constants.EventSrcPL))
        {
            try
            {
                EventLog.CreateEventSource(Constants.EventSrcPL, Constants.EventLogPL);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
            }
        }
    }
}
else
{
    usingResource = 0;
}

Does not solve the issue when the source is created by a different application in the exact time you are accessing the event log.

Edited: made modifications that account for the delayed creation of a EventSource.

Jaroslav Jandek
I had a breakpoint in my code so wasn't seeing thread issues, but I've added a `lock(...)` to guard the test/create similar to your `Interlocked.Exchange` but I'm still seeing the error.
JLWarlow
@JLWarlow: It takes some time to create the resource. So if you execute the code twice, you may get the exception. I have modified the code to account for the problem.
Jaroslav Jandek
+1  A: 

Found the problem after digging in to Sysinternals' Process Monitor a little more:

Calling EventLog.Exists("MyLog");

Logs Name not found, as expected in:

KLM\System\CurrentControlSet\services\eventlog\MyLog

Calling EventLog.SourceExists("MySource");

Checks several places, name not found in as expected:

HKLM\System\CurrentControlSet\services\eventlog\Application\MySource
HKLM\System\CurrentControlSet\services\eventlog\HardwareEvents\MySource
HKLM\System\CurrentControlSet\services\eventlog\Internet Explorer\MySource
HKLM\System\CurrentControlSet\services\eventlog\Key Management Service\MySource
HKLM\System\CurrentControlSet\services\eventlog\Media Center\MySource
HKLM\System\CurrentControlSet\services\eventlog\ODiag\MySource
HKLM\System\CurrentControlSet\services\eventlog\OSession\MySource
HKLM\System\CurrentControlSet\services\eventlog\Security\MySource
HKLM\System\CurrentControlSet\services\eventlog\System\MySource
HKLM\System\CurrentControlSet\services\eventlog\VisualSVNServer\MySource
HKLM\System\CurrentControlSet\services\eventlog\Windows PowerShell\MySource
HKLM\System\CurrentControlSet\services\eventlog\Application\MySource
HKLM\System\CurrentControlSet\services\eventlog\HardwareEvents\MySource
HKLM\System\CurrentControlSet\services\eventlog\Internet Explorer\MySource
HKLM\System\CurrentControlSet\services\eventlog\Key Management Service\MySource
HKLM\System\CurrentControlSet\services\eventlog\Media Center\MySource
HKLM\System\CurrentControlSet\services\eventlog\ODiag\MySource
HKLM\System\CurrentControlSet\services\eventlog\OSession\MySource
HKLM\System\CurrentControlSet\services\eventlog\Security\MySource
HKLM\System\CurrentControlSet\services\eventlog\System\MySource
HKLM\System\CurrentControlSet\services\eventlog\VisualSVNServer\MySource
HKLM\System\CurrentControlSet\services\eventlog\Windows PowerShell\MySource
HKLM\System\CurrentControlSet\services\eventlog\MyLog

However, calling EventLog.CreateEventSource("MySource", "MyLog");

Finds MyLog in the following registry location and errors:

HKLM\System\CurrentControlSet\services\eventlog\Application\MyLog

Removing "HKLM\System\CurrentControlSet\services\eventlog\Application\MyLog" and re-running fixed my problem!

Looks like the .Exists don't look in all the places .CreateEvent does!

JLWarlow