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);
        }
    }
}

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/

Hosted Build has errors for missing reference Crystal reports libraries

I was planning a migration for my solution from a build on my local machine to a build in Azure Devops. I want to use the Hosted VS2017 because then I do not have to worry about maintaining local Build servers.

When I added the solution to Azure and set up a build pipeline I encountered the following errors in the MSBuild log:

2019-01-10T10:11:49.9382855Z ##[error]Notepad\CrystalReportsViewer.cs(8,7): Error CS0246: The type or namespace name ‘CrystalDecisions’ could not be found (are you missing a using directive or an assembly reference?)
2019-01-10T10:11:49.9412999Z ##[error]Notepad\CrystalReport1.cs(153,53): Error CS0246: The type or namespace name ‘RequestContext’ could not be found (are you missing a using directive or an assembly reference?)
2019-01-10T10:11:49.9414407Z ##[error]Notepad\CrystalReportsViewer.cs(14,16): Error CS0246: The type or namespace name ‘ReportDocument’ could not be found (are you missing a using directive or an assembly reference?)
2019-01-10T10:11:49.9415960Z ##[error]Notepad\CrystalReport1.cs(19,35): Error CS0246: The type or namespace name ‘ReportClass’ could not be found (are you missing a using directive or an assembly reference?)
2019-01-10T10:11:49.9430403Z ##[error]Notepad\CrystalReport1.cs(24,32): Error CS0115: ‘CrystalReport1.ResourceName’: no suitable method found to override
2019-01-10T10:11:49.9432260Z ##[error]Notepad\CrystalReport1.cs(33,30): Error CS0115: ‘CrystalReport1.NewGenerator’: no suitable method found to override
2019-01-10T10:11:49.9433304Z ##[error]Notepad\CrystalReport1.cs(42,32): Error CS0115: ‘CrystalReport1.FullResourceName’: no suitable method found to override

I found a solution for this issue adding a pre-build event:

First I needed to add the CRRuntime msi and a pre-build.bat file to my solution:

The content for the pre-build file is an administrator installation of the CRRuntime msi. The command is:
msiexec /a “%1CRRuntime_64bit_13_0_23.msi” /quiet /norestart /log “%1CRRuntime_64bit_13_0_23_install.log”. I only want this to be installed when building a release (in Azure). For this I added the condition to only install for release builds.

if %2 == “release” msiexec /a “%1CRRuntime_64bit_13_0_23.msi” /quiet /norestart /log “%1CRRuntime_64bit_13_0_23_install.log”

Last I have added a pre-build event command line for the solution:
“$(ProjectDir)pre-build.bat” “$(ProjectDir)” “$(ConfigurationName)”

That’s that. Now the host will install the Crystal reports run time before building the solution.