There are certain circumstances in our application where non-fatal errors occur and the application recovers.
An example of this failing to correctly identify some importable items when populating said items to a selection list. The errors won't crash the app but a user would be alerted that some of the items failed to load.
In this case, the error is logged to the Application event log as a warning. It's a non-fatal error that the app recovers from, but logging to the event log allows us to see the original error if need be.
Our problem is that the software needs to be able to be installed with a Power User account. Not being an admin account, we won't have the ability to create custom event sources for the application.
The aim is to write the errors instead to the "Application" event source (which already exists appears in the Application event log). Doing this, however, causes text similar to the following to also be included.
The description for Event ID 0 from source Application cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
This is because the EventID is 0 when we write it. This approach will get the job done, but is there a a better way? Is there a non-admin way to specify the EventID for the Application Event source to indicate that it came from our app?
The error you see as The description for Event ID 0 from source Application cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. is the result of the Application source's registered event message file not having an entry for event id 0. The message you see is the result of getting the template for the message id from the event message file and formatting it with the event payload.
I would not recommend in general that you hijack a source you don't own. Whoever is consuming those events has specific expectations about what they mean and what information they carry.
Regarding Is there a non-admin way to specify the EventID for the Application Event source to indicate that it came from our app?, what do you expect that event id specification would mean? The source is what determines where the event came from.
EDIT:
You will get the error in event viewer regardless of whether you provide an event id other than 0, because that source does not have an event message file registered. And even if it did, you would either have to use event ids that have an entry in the message file (confusing the consumers of the events) or event ids that do not have an entry and still get the error.
You are able to pass the Application Event ID as a parameter: ( example : 234 )
EventLog.WriteEntry("Application", "your log message here", EventLogEntryType.Warning, 234);
Further reading into EventLog.WriteEntry Method
http://msdn.microsoft.com/en-us/library/xzwc042w.aspx
Related
I am using Wix and installing an event log like:
<util:EventSource Log='MyLogName' Name='MyLogSource' EventMessageFile='%systemroot%\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll' />
I have a service that runs and tries to log to MyLogSource after installation. It does not begin to log unless I restart my system.
However, if I create the log in C# code, I can immediately log. The C# code can be in my service OnStart()
EventLog.CreateEventSource("MyLogSouce", "MyLogName");
I have a Systems.Diagnostics.EventLog instance named eventLog in my service class that is initialized like:
eventLog .Source = "MyLogSource"; // instance variable created in InitializeComponent()
To clarify, if I use Wix to create the event source (and therefore don't use the C# code to create it), then when the service starts and starts logging, nothing goes in the log. I have to reboot and then everything works.
However, if I comment out the Wix part to create the event source and do it in C# code, then when I start logging, the data goes in the log and no restart is necessary. My service does not really depend on any other services.
Is there some kind of trick to get it to work immediately if I install using Wix? Is there some way to use a <ServiceControl /> entry for my component so that I can restart or stop and start a service so that logging works without rebooting?
Update: 28 Oct 2021
I did go digging through the EventLog source code. It does not restart any services. However, it creates two event sources when creating an event source. When creating an Event source from WiX, it just creates the one event source.
So in Wix if I'm creating MyLogSource and MyLogName, it creates just the registry entries for those items.However, in the C# source code when calling the EventLog.CreateEventSource API, with the same arguments, it does create those items, however, it also creates another event source named MyEventLog.
So, in the registry tree, there is the event log MyEventLog, but under the key are the two event sources MyEventSource and MyEventLog.
My application is in C#.NET and it is deployed on different machines. Users of my application have normal access rights ( no ADMIN rights). On a few system I am getting System.Security.SecurityException. It says "System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security"
I did a few workarounds :-
on one machine I launched my app with admin rights, It worked fine - No issue.
I added user group in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security.
It worked fine.
I dont want to go to every machine and do above workarounds. I need any generic workaround that can be applied once in all machine.
Any help?
Writing down a few lines of code :-
Config file :-
<add key="E_Source" Value="ABC">
C# code
Public static readonly string E_Source = ConfigManager.GetString("E_Source");
EventLog.writeEntry(E_Source, logtext, logtype);
Thanks in advance
To find the Source you want to write, .NET enumerates through all event logs. If it doesn't exist, .NET will eventually try enumerating through the Security log, for which you don't even have read rights as normal user. Thus, you get a SecurityException.
So you have to make sure that the event log exists (which AFAIK you can't do without triggering the exception). Normally, you would do that as part of your setup/install. Then, when writing, catch the SecurityException and handle it as appropriate (ex. show an error message that you couldn't write to the log).
If you're writing to the EventLog programmatically, you will need to create an event source with elevated permissions, as noted in the documentation on the EventLog class:
https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog%28v=vs.110%29.aspx
I created an event log creator and it works perfect locally. When trying to create an event log remotely it gives me this message:
If the event originated on another computer, the display information
had to be saved with the event.
And it adds it to the event log.
My current method involves making registry changes on the remote servers. I read online that you can perform an event log remotely using a web service? I am completely lost in creating a web service as I have never made one before, can someone point me in the right direction. I'm also trying to avoid making registry changes on remote servers because they are in a production environment.
My current code:
else if (RemoteText.Text != "")
{
int EventID = Convert.ToInt32(EventIdText.Text);
string myLogName = "";
if (!EventLog.SourceExists(SourceText.Text))
{
//Create source.
EventLog.CreateEventSource(SourceText.Text, myLogName, RemoteText.Text);
Console.WriteLine("Creating EventSource");
}
else
{
// Get the EventLog associated if the source exists.
myLogName = EventLog.LogNameFromSourceName(SourceText.Text, RemoteText.Text);
EventLog myEventLog1 = new EventLog(myLogName, RemoteText.Text);
myEventLog1.Source = myLogName;
// Write an entry into log.
myEventLog1.WriteEntry("This is for your information",
EventLogEntryType.Error, EventID);
}
MessageBox.Show("Event Creation was SUCCESSFUL");
My goal is to remove the generic message on remote computer and avoid making registry changes on remote computer.
Creating an event source does indeed need write access priviliege on the HKLM\System\CurrentControlSet\eventlog key.
Try EventSourceCreationData, you may be missing the message file.
If you have administrator access on the remote machine and that said servers do not have remote registry turned off, you could use WMI to make registry permission changes and try your approach again.
If the event originated on another computer, the display information had to be saved with the event
You get this error if the event source is undefined. When you write an event log entry to the event log you basically only write an ID and some parameters associated with the event log entry. When you then view the event log entry Windows will use the message file associated with the event source to actually format the entry. From the ID a message template is retrieved and the parameters are replaced in the message template to create the formatted message that you can view in the event viewer. This approach makes it possible to provide translated event log messages for different language versions of Windows.
If the event source is undefined Windows cannot locate the message file and when you try to view the event log entry in the event viewer you get the error that you describe.
So to correctly log an event log entry to a source on a computer you need to create the source and this requires administrative write access to the registry (it can be done using an elevated installer). So your current approach seems to be the correct one and not something you should try to avoid.
Often .NET developers do not have any experience working with event log message files. The basic API in .NET to write to the event log will register and use a generic message file that simply substitutes whatever string parameter you supplied into the formatted message. This makes is quite easy to write to the event log from .NET but it also makes it a bit confusing because you do not realize that there is an intermediate message file required for it to work.
I need my service to check for existence and structure of certain files during its startup and exit/fail/stop if some conditions aren't met.
I read this thread: What is the proper way for a Windows service to fail?
but it does not help.
I set the ServiceBase.ExitCode property non-zero and then call ServiceBase.Stop. But I get 5 event log entries. See below:
Starting service. (I log this event via code)
Config.xml file not found. (I log this ERROR event via code)
Service stopped successfully. (SCM logs this message)
Service started successfully. (SCM logs this message)
Service cannot be started. The handle is invalid (SCM logs this message)
As you see everything goes OK except for the last two entries. Why are they there? What can I do to properly shutdown the service during startup? Why doesn't SCM see the service as stopped/failed?
You don't provide enough code to really know, but I suspect you are trying to validate the service and stop it in either the constructor or the OnStart. The way I like to handle services is start my timer in the OnStart. In the first interval of the timer I can validate all the code, if its invalid close the Service. If its valid, reset the interval of the timer to how frequently I want it to run then set a bool that tells it not to check for validity of files again.
What is the return code you are using for your ExitCode? If it matches the corresponding windows ExitCode, then that is what will be recorded by SCM. I'm assuming you are returning a 6 for your ExitCode.
The other thing is if you can run on Default values do that, let Config.xml be missing and just record the problem in the EventLog. "Configuration file Missing"
If you really want it to just abort during OnStart, set your ExitCode and then Throw an Exception (InvalidArgumentException, InvalidOperationException) for example
This article also has some good advice. .NET: Which Exception to Throw When a Required Configuration Setting is Missing?
You are trying to start second instance of service (another service registered for the same .exe)
I was trying to find a solution for issue,,that is one Service repeatadly going on restart which is making the issue.When i checked the event log
i can see one waring before the restart occurs
Warning is
"The description for Event ID ( 1 ) in Source ( ZENworks Patch Management Agent ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: A connection between a PDDM and the agent was closed. [TaskManager.cpp:168]."
We know PDDM.exe is a process that runs in the background on the agent machine. It handles deployments notification. The agent will log this message when PDDM.exe exits from memory. The following events will cause PDDM.exe to exit from memory: User logging off, computer shutting down, PDDM.exe gets killed from task manager..
But i dont know how to proceed with this issue,Can any one help me regarding this
I have two options one is Reinstall the application,other is reboot the OS
Any other options?