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




3 comments:

  1. Hy i'm trying to understand where in VB is :
    "whereas for VB, it is located in your service file."
    What file, in your DEMO on VB you do not have the :

    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

    where should i put this ?

    ReplyDelete
    Replies
    1. The code is at the service's designer file. In the demo app perspective, it is in WSDemoVB.Designer.vb

      Delete
  2. Nice tutorial, thank you ...

    ReplyDelete