Showing posts with label Windows Service. Show all posts
Showing posts with label Windows Service. Show all posts

Friday, 13 November 2015

List of Additional Funtionality to Include During Self Install Windows Service in C# & VB

To continue on the previous post about self install a windows service. http://jaryl-lan.blogspot.com/2014/09/create-simple-windows-service-and-self.html. Have you ever been wondering what else can you do during installation of the windows service? Well, you can include methods or functionalities that only requires to execute once that are not suitable to be called during the windows service is running. So, let's look into the list of methods or functionalities to be included.


Create Event Log & Source

If you need to write logs into the event log with custom log and source, it is advisable to create them during windows service installation. This is because writing log into event log requires the log and source to be there. The good thing is that if it does not exist, the code will attempt to create the log and source. But if the Windows Service is launched with a user with low-privilege, then the service will throw an exception due to the user did not have the permission to creation of log and source. For more detail on dealing with Event Log, you can refer to the following link. http://jaryl-lan.blogspot.com/2015/09/create-configure-and-write-to-event-log.html


Automatically Start / Stop the Windows Service During Installation & Uninstall

To simplify the installation, you may want to consider starting the service for the user after installation. Otherwise the user need to manually start the windows service by launching the Services window to find the installed windows service. Also, there's a high chance that the user is not aware of the windows service name.

[C#]
using (var serviceController = new ServiceController(_serviceName))
{
    if (serviceController.Status != ServiceControllerStatus.Stopped) return;

    serviceController.Start();
    serviceController.WaitForStatus(ServiceControllerStatus.Running);
}

[VB]
Using ServiceController As ServiceController = New ServiceController(_serviceName)
    If Not ServiceController.Status = ServiceControllerStatus.Stopped Then
        Exit Sub
    End If

    ServiceController.Start()
    ServiceController.WaitForStatus(ServiceControllerStatus.Running)
End Using

Other than that, you may want to stop the service before uninstall the windows service. When the windows service is stopping, the OnStop method will be executed, so you can write the necessary code to do some cleanup in the method.

[C#]
using (var serviceController = new ServiceController(_serviceName))
{
    if (serviceController.Status != ServiceControllerStatus.Running) return;

    serviceController.Stop();
    serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
}

[VB]
Using ServiceController As ServiceController = New ServiceController(_serviceName)
    If Not ServiceController.Status = ServiceControllerStatus.Running Then
        Exit Sub
    End If

    ServiceController.Stop()
    ServiceController.WaitForStatus(ServiceControllerStatus.Stopped)
End Using


Windows Service Recovery

For those who are unaware about Windows Service Recovery, you can actually configure them in the Recovery Tab by navigating to the Windows Service's properties and look for the Recovery Tab. But it can be tedious to configure each and every Windows Service that you have installed. To simplify this, recovery settings should be set during Windows Service installation. There are couple of ways to do it, but I will only demonstrate how to set it using command line with Process class.

The arguments specified in the code below will do the following:
  • The error count will be reset after 3600 seconds.
  • The Windows Service will restart itself when it gets terminated unexpectedly for the first and second failure (After 5 minutes).
  • The subsequent failure will attempt to execute the windows service with the argument "-email" (After 30 seconds).

[C#]
using (var process = new Process())
{
    var startInfo = process.StartInfo;
    startInfo.FileName = SC_COMMAND;
    startInfo.Arguments = string.Format("failure \"{0}\" reset= 3600 actions= restart/300000/restart/300000/run/30000 command= \"\\\"{1}\\\" -email\"", _serviceName, executableLocation);

    process.Start();
    process.WaitForExit();
}

[VB]
Using process As Process = New Process()
    Dim startInfo = process.StartInfo
    startInfo.FileName = SC_COMMAND
    startInfo.Arguments = String.Format("failure ""{0}"" reset= 3600 actions= restart/300000/restart/300000/run/30000 command= ""\""{1}\"" -email""", _serviceName, executableLocation)

    process.Start()
    process.WaitForExit()
End Using


Display Error Message for Failed Installation / Uninstall

It is best to show an error message whenever an installation or uninstall for the windows service is being performed, otherwise it will be hard and tedious to trace the problem (Check installation log and Event Log) & the end user that does the installation or uninstall may not aware on how to trace the problem. With a proper and meaningful error message being displayed, the user will be aware of the error and might be able to perform the necessary action or amendment to fix the problem and then retry the installation or uninstall of the windows service.

The sample code can be obtained here. https://onedrive.live.com/redir?resid=E6612168B803803D!345&authkey=!AOIm5LtxJbwXoQo&ithint=file%2czip




Sunday, 7 September 2014

Create Simple Windows Service and Self Install in C# & VB

Feeling troublesome for using installutil to install Windows Service? Having to navigate to C:\Windows\Microsoft.NET\Framework\<your framework version> or C:\Windows\Microsoft.NET\Framework64\<your framework version> just to install or uninstalling Windows Service in server environment? Well, there's a more convenient way to perform installation and uninstallation, which is to write code for the Windows Service to self install / uninstall.

Before we go into that, let's create a simple Windows Service Project.

1) Select Windows Service and fill up your desired project name.

Visual Studio 2013 New Project


2) For this demo, Timer will be used to write to event log for every 10 seconds. So, open up the service in View Code mode or click on F7. 

Include the following namespace
[C#]
using System.Timers;
using System.Diagnostics;

[VB]
Imports System.Timers
Imports System.Diagnostics


Create a Timer variable
[C#]
private Timer _timer = null;

[VB]
Private _timer As Timer


OnStart Method - Initialize the timer that will write to event log for every 10 seconds. This method will run when the service started.
[C#]
_timer = new Timer();
_timer.Enabled = true;
_timer.Interval = 10000;
_timer.Elapsed += (sender, e) => {
    EventLog eventLog = new EventLog();
    eventLog.Source = "Windows Service Self Install Demo";
    eventLog.WriteEntry(DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") + " - Windows Service Self Install Demo.");
};

[VB]
_timer = New Timer
_timer.Enabled = True
_timer.Interval = 10000

AddHandler _timer.Elapsed, AddressOf OnTimedEvent


Private Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
        Dim eventLog As EventLog = New EventLog()
        eventLog.Source = "Windows Service Self Install Demo VB"
        eventLog.WriteEntry(DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") + " - Windows Service Self Install Demo.")
End Sub


OnStop Method - To stop and release resource used by the timer. This method will run when the service is stopped.
[C#]
_timer.Close();

[VB]
_timer.Close()


3) Create a ProjectInstaller by double click or shift + F7 or open service in View Designer mode, right click on any gray area and click Add Installer. A ProjectInstaller file will be created in your project.

Windows Service Designer

4) Double click or shift + F7 or open ProjectInstaller in View Designer mode. Choose your desired properties for both serviceProcessInstaller1 and serviceInstaller1. In my case, this is what i set.

serviceProcessInstaller1
- Account : LocalSystem

serviceInstaller1
- StartType : Automatic
- Description : Demo Self Install Windows Service
- DisplayName : Windows Service Demo
- ServiceName : Windows Service Demo

Service Process Installer

Service Installer


With this, the windows service is created. Next would be to create a self install windows service. In the main method, add the following lines of code to pass in argument. In C# the main method is located in "Program.cs" file, whereas for VB, it is located in your service file.


[C#]
if (System.Environment.UserInteractive)
{
    if (args.Count() == 1)
    {
        if (args[0] == "-install")
            ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });

        if (args[0] == "-uninstall")
            ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
    }
    return;
}

[VB]
If System.Environment.UserInteractive Then
    If args.Count() = 1 Then
        If args(0) = "-install" Then
            ManagedInstallerClass.InstallHelper(New String() {Assembly.GetExecutingAssembly().Location})
        End If

        If args(0) = "-uninstall" Then
            ManagedInstallerClass.InstallHelper(New String() {"/u", Assembly.GetExecutingAssembly().Location})
        End If
    End If
    Exit Sub
End If


Once it is done, compile your project. Next is to show how to install or uninstall the windows service. Here are the couple of ways to install / uninstall the windows service.


[Command Prompt]
1) In command prompt window, navigate to your bin folder that contain the service executable file. 

2) To install, type and run [Windows Service Assembly Name].exe -install. To uninstall, just change -install to -uninstall and execute.


path.exe -install

path.exe -uninstall


[Shortcut]
1) Navigate to your bin folder that contain the service executable file. 

2) Create a shortcut from the service executable file. Right click on it and select Properties

3) Select Shortcut tab.

4) In the target field, for installation, add -install after your executable path. For uninstallation, just change -install to -uninstall or you can create 2 different shortcut for install and uninstall respectively.

5) Run the shortcut.

path -install

path.exe -uninstall


[Visual Studio]
1) Right click on your Windows Service project and click Properties.

2) Select Debug tab.

3) Under Start Options. For installation, type -install in Command line arguments field. For uninstallation, just change -install to -uninstall.

4) Start / debug your project.

-install

-uninstall


By using one of the methods above to install, the windows service should appear in the Service window. If you are unsure how to open the service window, you can do one of the following.
- At Run window, Type services.msc and click OK button, or
- Control Panel > Administrative Tools > Services.

Services Window

That's all for creating a Self Install.

Here's the source code : https://onedrive.live.com/redir?resid=E6612168B803803D!358&authkey=!AE6WfmdHMIoWpTg&ithint=file%2czip

If you would like to find out more on what else you can do during Self Install other than just installing windows service, then you may want to consider take a look here http://jaryl-lan.blogspot.com/2015/11/list-of-additional-funtionality-to.html