Change settings for eventlog in Service installer

I was developing a Windows service. Everything went smooth until I was asked to add logging for the service into a separate log file in the event viewer. I want to share my journey with you so it may help finding a solution for similar or the same issue.

After I had learned to install a service using a service installer, I ran into some troubles configuring the event viewer. My service had three logging options. First is to a text file on disk, second is to the Windows Event Viewer and I added an extra option to send a message to a messaging app. All service issues where logging fine. As a last option I was asked to log to a separate log in the event viewer like this:

First I tried adding all kind of options to my logging library to check, add and change the logging destination. That didn’t work and I found that the log needed to be set during initial installation of the service. Reason that previous attempts failed was that when changing these settings, the application needs admin privileges and changing logging options afterwards needed the machine to be rebooted etc.

I searched the internet for a solution and after a couple o hours I stumbled upon this article: https://stackoverflow.com/questions/115488/what-is-the-most-reliable-way-to-create-a-custom-event-log-and-event-source-duri

The post of Simon Mattes in this article helped me out. I altered the code a bit for my own use:

public ProjectInstaller()
{
InitializeComponent();
//Skip through all ServiceInstallers.
foreach (ServiceInstaller ThisInstaller in Installers.OfType())
{
//Find the first default EventLogInstaller.
EventLogInstaller ThisLogInstaller = ThisInstaller.Installers.OfType().FirstOrDefault();
if (ThisLogInstaller != null)
{
//Modify the used log from "Application" to the same name as the source name.
//This creates a source in the "Applications and Services log" which separates your service logs from the default application log.
ThisLogInstaller.Log = "TestApplication"; //ThisLogInstaller.Log = ThisLogInstaller.Source;
ThisLogInstaller.Source = "TestSource";
}
}
}

Check out this post on adding an installer to your application: http://kannekens.nl/registering-installing-a-windows-service-part-2/


Registering / installing a Windows service part 2

In this article I want to describe an easy way to add an easy installer to a Windows Service project.

Steps are: – Add the installer for the service
– Configure the service parameters
– Add parameters to start up of the program


Add the installer for the service can be done when you open the service.cs. This will show a gray screen with two links:

Right click this screen and select Add installer in the pop up menu. This will add a ProjectInstaller.cs file with a ProjectInstaller class inside.

Open the Projectinstaller file. This will show two components.

Change settings for the two components according to your needs.

Last step is to add the installer to the program start up. For this we need to change the Program.cs.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            //Install service
            if (args[0].Trim().ToLower() == "/i")
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(
        new string[] { "/i", Assembly.GetExecutingAssembly().Location });
            }

            //Uninstall service                 
            else if (args[0].Trim().ToLower() == "/u")
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(
        new string[] { "/u", Assembly.GetExecutingAssembly().Location });
            }
        }
        else
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
            new ServiceMonitor()
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}

Debugging Windows Service in Visual Studio

After some searching and testing how to debug a windows service, I found that for me the following solution is working very well.

First register your service as a service on your machine. This can be done with a few simple steps. How to do this is described in this article: http://kannekens.nl/registering-installing-a-windows-service/

Next add a line / lines Debugger.Break(); in your code where you want the debugger to start. Now compile in debug mode clicking in Visual Studio menu: Build, Build Solution while the Configuration Manager is set to Debug.

After the application compiled successfully we can stop and start the service to ensure these modifications are run:

I used the tips from https://docs.microsoft.com/en-us/dotnet/framework/windows-services/how-to-debug-windows-service-applications and https://stackoverflow.com/questions/104235/how-can-i-use-debugbreak-in-c.

Right click the Visual Studio application and select more…, Run as administrator

Click Debug, Attach to Process in the Visual Studio menu.

This will open a dialog where you need to select the right process to debug. Check the Show processes from all users checkbox. Find your Service process and click Attach.

Registering / Installing a Windows Service

After you have written your Windows Service in Visual Studio you might want to run this to test and use the service.

You can run your service with a few simple steps: I used a service called ServiceName in the following examples.

First start a command prompt: cmd (as admin)

Install a service is done using sc create, syntax:
sc create ServiceName binPath=”pathto.exe”. If the command was successfull it will report SUCCESS.
Example:

Install a service is done using sc create, syntax:
sc create ServiceName binPath=”pathto.exe”.

If the command was successfull it will report SUCCESS. Example:

C:\WINDOWS\system32>sc create ServiceName binPath=”C:\repos\ServiceMonitor\ServiceName\bin\Debug\ServiceName.exe”
[SC] CreateService SUCCESS

To start the service use the command net start, syntax:
net start ServiceName

C:\WINDOWS\system32>net start ServiceName
The ServiceName service is starting.
The ServiceName service was started successfully.

To stop the service use the command net stop, syntax:
net stop ServiceName
Example:

C:\WINDOWS\system32>net stop ServiceName
The ServiceName service is stopping.
The ServiceName service was stopped successfully.

To delete / uninstall the service use sc delete, syntax:
sc delete ServiceName
Example:

C:\WINDOWS\system32>sc delete servicename
[SC] DeleteService SUCCESS

UPDATE 28-2-2019: New post, I added a installer in the executable. This enables the service to install running the executable. Read on in this follow up article: http://kannekens.nl/registering-installing-a-windows-service-part-2/