Pete Hilde
Pete Hilde

Reputation: 709

How to register the automatically registered Windows Service EventLog property to another log than the Application log?

I'm currently creating a Windows Service and just figured out (thanks to this answer) how to configure the service installer in order to create a custom event log source during installation. As I already figured out by myself, these custom event log sources require elevated privileges to be registered. And that's the reason why the registration happens during installation - because the service installation is always executed with elevated privileges. So far, so good.

However, I'm not 100% satisfied with that solution because, as it is stated in the documentation of ServiceInstaller:

The Log property for this source is set by the ServiceInstaller constructor to the computer's Application log.

And this is not what I want. I want the events to be registered in a custom log called "MyCustomLog". Moreover, I cannot just set my service's ServiceBase.EventLog.Log to "MyCustomLog". How can I individually set my service's EventLog.Log? And where do I have to do this?

As I didn't find an answer for my question yet, I thought of creating a custom view for my service events which should have then looked like below:

enter image description here

It does not replace a custom event log as the events are still registered to the Application log, but it enables me to have an overview of certain events that happened in my service, just like it would be in a custom event log. So, how do I programmatically create such custom views? Is that possible? And if so, where do I need to create them? Does the creation require elevated privileges, so it needs to be done inside the ServiceInstaller? Or could this easily be done inside my service's constructor?

I would appreciate answers concerning the feasibility of both of the approaches!

Upvotes: 0

Views: 1003

Answers (1)

Matt Davis
Matt Davis

Reputation: 46044

More details here. The following should work, minimally, in Visual Studio 2017 and Visual Studio 2019.

  1. In the Solution Explorer of Visual Studio, double-click your service component, i.e., the component that derives from ServiceBase. Doing this will open the component in the [Design] view.
  2. With the [Design] view open, open the Properties grid by pressing F4 (or View|Properties Window from the menu).
  3. In the Properties grid, set the AutoLog property to false. This will prevent events from being written by default to the Windows Application log .
  4. If you have not already done so, right-click anywhere in the [Design] view of the service component, and select the Add Installer menu option. This adds a component to your solution named ProjectInstaller by default.
  5. Note that the new ProjectInstaller is automatically opened to its respective [Design] view. To get to its code, right-click the ProjectInstaller.cs file in the Solution Explorer, and select the View Code menu option.
  6. Change the contents of that file to look like the following. This updates the EventLogInstaller to use the custom log name of your choice.
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Diagnostics;

    namespace YourProjectNamespace
    {
        [RunInstaller(true)]
        public partial class ProjectInstaller : Installer
        {
            public ProjectInstaller()
            {
                InitializeComponent();

                EventLogInstaller installer = FindInstaller(this.Installers);
                if (installer != null)
                {
                    installer.Log = "YourEventLogName"; // enter your event log name here
                }
            }

            private EventLogInstaller FindInstaller(InstallerCollection installers)
            {
                foreach (Installer installer in installers)
                {
                    if (installer is EventLogInstaller)
                    {
                        return (EventLogInstaller)installer;
                    }

                    EventLogInstaller eventLogInstaller = FindInstaller(installer.Installers);
                    if (eventLogInstaller != null)
                    {
                        return eventLogInstaller;
                    }
                }
                return null;
            }
        }
    }
  1. The last step is to tie the service component to the custom event log you named in Step 6. To do that, right-click the service component in the Solution Explorer, and select the View Code menu option. Update the constructor to the following:
    public YourServiceName()
    {
        InitializeComponent();

        // This ties the EventLog member of the ServiceBase base class to the
        // YourEventLogName event log created when the service was installed.
        EventLog.Log = "YourEventLogName";
    }
  1. When you install the service, the YourEventLogName should be created on the system. If the Event Viewer is already open, you'll probably have to refresh it. If it's still not visible, you might need to log something to it (I don't recall the details). In any case, to write log information to the custom event log from your service, use the EventLog member of the service component, e.g.,
    protected override void OnStart(string[] args)
    {
        EventLog.WriteEntry("The service was started successfully.", EventLogEntryType.Information);
    }

    protected override void OnStop()
    {
        EventLog.WriteEntry("The service was stopped successfully.", EventLogEntryType.Information);
    }

    protected override void OnShutdown()
    {
        EventLog.WriteEntry("The service was shutdown successfully", EventLogEntryType.Information);
    }

Upvotes: 1

Related Questions