I want to make a log with errors during the execution of my app. I'm trying to write an event to the windows Event Viewer with a VCL form application with C++ Builder XE5.
I'm using Vcl.SvcMgr.TEventLogger class.
The code in the header file is :
TEventLogger *Event;
The code in the cpp file is :
Event=new TEventLogger("MySource");
Event->LogMessage("MyMessage");
But beside my message, in the error description in the Event Viewer there is a message : "The description for Event ID 0 from source MySource cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted." . How can I remove that description and write only the message that I want? Should I be using other C++ class? I couldn't find any documentation about this class. The idea of using Event Viewer is that when the application is running on an user with restricted rights he won't be able to write to files, meaning I can't just type into a ".txt" file. If anyone else has a different idea how to make a log with errors, please share! :)
Thanks in advance,
Zdravko
This message normally shows up if there is no message files set up within your application. In contrast to Unix syslog and similar logging packages, the Windows event log normally combines messages from the message file and the text you want to log and if there is no message file set up and registered, the event view complains about it.
Related
Probably this already was answered here, but i not found.
Then i want know how execute a c++ console application/service (installs itself as service) of way that i can see all output's (printf()) during your execution (similar to how happens in a normal console application when system("pause");is used in main())? until now i'm able to see you console window only while Avast DeepScreen is executing he :-).
Thanks in advance.
EDITION:
I already insert getchar(); in ServiceMain() and a while (true) ... Sleep() but without success.
A service does not have a console window. And even if it did, a service does not run in an interactive desktop, so you couldn't see such a window anyway.
You need to rethink your logging approach. Either
write your log messages to the Windows Event Log, and use the Windows Event Viewer to see the messages.
create a separate visual app that runs in the user's interactive desktop and communicates with the service process to receive log messages. Then you can display the messages however you want.
Well, take the execution of any program using a c++ program, you can simply do it using the command prompt.
Just type in :
system(“path to the program”);
And, the program will be executed. If it’s a console window program, it will pop-up.
You can see the outputs, well, follow these :
1 The System.Diagnostics.Trace class has a similar interface to the Console class so you could migrate your code quite easily to this.
2 It can then be configured to output to a file. You can use the System.Diagnostics.EventLog class to write to the Event Log which you can then monitor using Event Viewer.
3 You can use the third-party open-source log4net library which is very flexible.
I have created a category file to the Event Logger, but the category names do not show up in Event Logger.
If I however open the log from C:\Windows\System32\winevt\Logs, the category names show up. The category name also show up if I use following PowerShell.
$eventlog = New-Object System.Diagnostics.EventLog("MyLog")
Write-Host $eventlog.Entries[0].Category
The .mc file looks like this:
MessageIdTypedef = WORD
LanguageNames=(
English=0x0409:MSG00409
Swedish=0x041D:MSG0041D
)
MessageId=1
SymbolicName=CAT_1
Language=English
Category 1
.
Language=Swedish
Kategori 1
.
MessageId=2
SymbolicName=CAT_2
Language=English
Category 2
.
Language=Swedish
Kattegori 2
.
; // Up to 22 categorys
In the registry, I have following:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MyLog\MySource]
"CategoryCount"=dword:00000016
"TypesSupported"=dword:00000007
"CategoryMessageFile"="C:\\path\\Messages.dll"
I have found https://social.msdn.microsoft.com/forums/windowsdesktop/en-us/3fed3069-ce0f-4168-8132-4d19d66fdd7e/windows-7eventlog-creating-custom-categories with the same problem, but no answer to the problem.
I have tried this in both Windows 7, 8 and Windows Server 2008 R2
Edit
I have created a test project to show what I have done. download it here
Try adding the machine's Authenticated Users or Users group to the message folder's security level. Keep the default permissions. Then either reboot or try to restart the EventLog service.
At an administrator command prompt: net stop eventlog
You will likely be prompted to shutdown other services. You must enter Y to continue. The services being shutdown will normally restart on their own so you just need to wait a few seconds. The eventlog service may fail to shutdown because another service has restarted, it may take a couple of tries to get everything down. Watch the resulting text closely for status.
I ran into this same issue while pointing the source registry information to my message folder in my VS project. I found that it started to work after I created a C:\Test folder with an admin user and referenced that instead. The only difference between this and the project folder was the two groups. Adding either of the two groups made things work. Taking them both away from either folder made it stop.
I also found that if I had matching MessageId's in my CategoryMessageFile and my EventMessageFile it ignored the CategoryMessageFile.
Another possibility, though obviously not the OP's issue (or language), that exhibits similar symptoms is when the EventMessageFile and the CategoryMessageFile have overlapping MessageIds. I am assuming this is a bug in the event log viewer utility when looking at a 'live' source, as the symptoms do not exist when using powershell, .NET, or directly opening the event log file in Event Viewer to parse the event logs.
In my situation, I have a .NET application and am using .NET APIs to create the event source using EventSourceCreationData to specify the CategoryResourceFile and CategoryCount. By default, the MessageResourceFile will be set to C:\Windows\Microsoft.NET\Framework\v4.0.30319\EventLogMessages.dll. The effect of these APIs causes the creation of the appropriate registry keys CategoryMessageFile, CategoryCount, and EventMessageFile. Important to note here is the message file from .NET helpfully adds messages from 0x0 to 0x000FFFF that are all defined as %1\r\n\x00 - essentially meaning when you create an event message in the default way, using EventLog.WriteEntry you see the string message that was logged regardless of the event id. If instead you use EventLog.WriteEvent, you pretty much need to use a specialized messages file (see docs on the EventInstance class). More Info
The symptoms are when looking at the live Event Viewer the Category as defined with the MessageId that was passed into the event log shows up as the integer instead of the string from the resource file. Note this is different behavior from if you had misconfigured the category resource file, permission issues, etc where you see the 'Task Category' as the integer but in parenthesis.
So for example, if you specified category id 8 and are expecting the localized category name 'My Category' the Event Viewer can show one of three things: (8) meaning the CategoryMessageFile or CategoryCount registry keys are misconfigured or there is a problem with the dll. My Category if everything is working as expected. 8 if you hit the issue I am describing.
Thanks to Rich Shealer's answer for the pointer. The problem is rather than getting the Category string from the CategoryMessageFile as one would expect, it is getting it from the MessageResourceFile - and since the .NET resource file merely is a formatting string that returns the first element of source data the numeric category id is generated.
There is no 'good' workaround, but in my use case of using metadata provided to log messages via a logging framework, and some filtering, messages generally have category and event id of zero, except for where I want to specifically set one when logging for a small subset of log messages. This means the logging framework is what is calling the APIs to write the log entries. A workaround is to declare MessageId of 0x0 to be %1 in the .mc file, and only start your event ids at a number higher than the number of categories you expect to have. Then configure the EventMessageFile in the registry or via the property MessageResourceFile to first specify the category file, the semicolon delimiter, then the .NET default resource file. This will properly show and messages logged with 0's for event id and category id, and for event ids greater than your category file the same behavior you previously had. However, any eventid with a number defined that conflicts with the category - well, you get the category name as the log message. You could also remove the message resource file but then you get the annoying 'resource cannot be found' message. I confirmed the behavior here but refuse to do this - will live with the missing text, as I mostly use APIs for analysis and it is correct there.
Sadly, I can't locate any open issue with the Windows Event Viewer - I see it broken in Windows 10 build 1909.
I was not able to understand how to log to a custom event log using c++.
I will explain better: googling around for hours I discovered that the most recent way to use windows log should be that named "Windows Event Log" built on top of ETW (here https://msdn.microsoft.com/en-us/library/windows/desktop/aa385780%28v=vs.85%29.aspx)
I want that my log events shows in EventViewer under "Application and services logs"\"MyAppCustomLog"
So I did these steps
- Edited registry creating the MyAppCustomLog entry (HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\EventLog\MyAppCustomLog)
created an Instrumentation Manifest (xml file) using the SDK utility "ecmangen", creating the manifest file MyAppLog.man
built the .rc and .bin and .h files using message compiler: mc -um MyAppLog.man -h . -z MyAppLog
registered the manifest using the wevtutil this way: wevtutil im MyAppLog.man
create a simple consolle application that calls the in MyAppLog.h (the header created by message compiler) in this way:
...
ULONG result = EventRegisterMyAppLog();
...
EventWriteMyAppLogSimpleEvent();
...
EventUnregisterMyAppLog();
...
But if I execute those methods where does the event go? How can I associate it to my custom event log? I could not figure it out...
Am I doing the wrong thing?
I am sure that some pieces are missing from my puzzle but which ones?
My question is: how to link the event I defined in manifest (MyAppLogSimpleEvent) to the custom event log MyAppCustomLog that I see in event viewer?
Could someone explain me how to set a relation between my events and the custom log?
In case this is the wrong way to do this (write events defined in some kind of manifest in a custom event log) could you please explain me what do I have to do?
Thank you very much for any help
I have several instances of Visual Studio 2008 opened and I want to open a source file in a specific instance.
I plan to do this with Win32 API and something like ShellExecute(...), but I can't find solution yet.
Is there any way to do so? Any thoughts?
Unless the application opening the file (VS2008) has a message handler set up to initiate opening a file (not sure if it does or not; this would be the easiest method), you could probably simulate a drag-and-drop of the file to the application's client area (via message sending directly to the client window's message handler). You would need to get a handle to the client window of VS2008 for the instance you are sending the message to.
Don't know what the purpose would be, though. You can generally call up a new instance to open the file using ShellExecute(), but that wouldn't refer to a specific instance that is already running.
Another method you might consider is to hook VS2008's message handler for the main window, and log all messages sent relating to menu commands. You might be able to determine if there is a message event associated with opening a file. Figuring out the parameters sent to the WndProc() function would be another story. Hopefully it would be sent as a string pointer (for the filename) to lParam.
You could try using AutoHotKey. It's got a built-in scripting language and has various alternative ways of identifying which application to send its messages to.
We've got an old legacy win32 service, developed with C++, and we've just recently noticed that when the service starts up and stops, there is an informational message in the event logs about our missing event descriptions. To be more precise, the message looks like this:
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.
So we understand what this means, basically we're missing a library which has a message table compiled into it. This way when the event ID for changing status (start/stop) arrives, it can look up the message and print it in the event logs.
The question is, for these universal messages (changing status etc) which pretty much every service is going to have, surely there are default message table that we can use, rather than having to go to the trouble of creating another project, just for this, adding registries and updating our installer.
Seems like a lot of hassle for something that should surely be a default somewhere? Like the standard win32 error messages?
I've created a number of managed services in the past, and I'm pretty sure we didn't need to do anything like this before!
So to wrap this up, I guess the answer is that the a new message table/file is always required, regardless (so no there are no default messages you can use), so I'll just have to chuck in a message table into my services resource file and add a registry entry to the installer.
Still find it baffling thought that every native service has it's own 'service has stopped/started' message...!
Thanks!