Richard
Mon Jun 14 09:59:00 CDT 2004
Paul J. Lay wrote:
> Here is the exact stament I use to log an event entry:
>
>
EventLog.WriteEntry("GIZMO",eventString,EventLogEntryType.Information,8001,7
> )
>
> I discovered through enumeration all of the event category strings
> that are defined. The 7 produces the category "Network" which is
> close to what my app does. I just dreamed up 8001, 8002, . I
> tried all day yesterday with the help of MSDN to register two
> additional categories: Exception and Trace Entry. I had no luck.
> This shouldn't be so difficult. Everything else works great. The
> Event Viewer displays GIZMO, the 8001 code, the category, and the
> eventString data.Thanks for your prompt reply.
Adding event messages has been debased in .NET (its actually a copy of the
VB6 mechanism). It does not work the way that the event log was designed to
work, and IMO the reason why its been implemented so badly is sheer
laziness on the part of Microsoft.
The problem you have is because .NET does not use message/category resource
files (these are resource only DLLs). A resource file has a 'template', a
format string, for each message using place holders for insert strings, when
you add the event you provide the ID of the format string and the insert
strings. The FormatMessage API will extract the format string, and insert
the insert strings in the appropriate places to create the complete message.
When you install .NET you get a message resource file with 65,000 format
strings like this:
%1
ie there is no attempt to use the functionality of FormatMessage. Horrible
and lazy.
Category values are handled by the event log in a similar way. You have a
resource DLL that has entries for each category (but no insert string place
holders), the DLL is registered in the system registry as containing
category strings. When the event log sees that the message is from your
resource it will load the DLL, extract the resource, obtain the appropriate
category string and print it out. There is no default way to do this in .NET
(again, I think the reason is because the designers of this class haven't
really used the event log to do anything useful). So what you are seeing is
the default categories defined by the system.
You can add your own category file and remedy some of these problems.
Basically find the key for your event log source here:
HKLM\System\CurrentControlSet\Services\EventLog\Application
and then add the CategoryMessageFile value to point to the category file and
CategoryCount to indicate how many categories you have defined, here's some
code to do this:
// name is the source name
// msgFile is the full path to the category message file
// count is the number of categories
static void CreateSource(string name, string msgFile, int count)
{
if (!EventLog.SourceExists(name))
EventLog.CreateEventSource(name, "Application");
RegistryKey hklm = Registry.LocalMachine;
string keyName = @"SYSTEM\CurrentControlSet\Services"
+ @"\EventLog\Application\"
+ name;
RegistryPermission perm = new RegistryPermission(
RegistryPermissionAccess.Create|RegistryPermissionAccess.Write,
@"HKEY_LOCAL_MACHINE\"+keyName);
RegistryKey el = hklm.OpenSubKey(keyName, true);
string file = Environment.CurrentDirectory + @"\" + msgFile;
try
{
el.SetValue("CategoryMessageFile", file);
el.SetValue("CategoryCount", count);
}
catch(Exception){}
}
static void DeleteSource(string name)
{
if (!EventLog.SourceExists(SourceName)) return;
RegistryKey hklm = Registry.LocalMachine;
string keyName = @"SYSTEM\CurrentControlSet\Services"
+ @"\EventLog\Application\"
+ name;
RegistryPermission perm = new RegistryPermission(
RegistryPermissionAccess.Write,
@"HKEY_LOCAL_MACHINE\"+keyName);
RegistryKey el = hklm.OpenSubKey(keyName, true);
try
{
el.DeleteValue("CategoryMessageFile");
el.DeleteValue("CategoryCount");
}
catch(Exception){}
EventLog.DeleteEventSource(name);
}
Now you need to create a message resource file and then register it with the
method above.
This is part of the example CategoryFiles.zip on
http://www.grimes.demon.co.uk/Other_Stuff.htm
Richard
--
my email evpuneqt@zicf.bet is encrypted with ROT13 (www.rot13.org)
sign up for my free .NET newsletter at
http://www.wd-mag.com/newsletters/