Skip to main content
Email Password   helpLost your password?

Introduction

Services can be installed using MSI (Microsoft Installer) by adding custom actions. This tutorial gives step-by-step details how custom action can be added which would install user service silently. It then modifies the registry entries for the service installed and logon user account based on user input.

Windows NT resource kit provides two utilities, srvany.exe and instsrv.exe which can be
used to allow any windows application to run as Windows Service, install and remove
any windows service.

Creating Custom Action Exe

Using following steps create a custom action executable:

using System.Text;
using System.Configuration.Install;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using System.Resources;
using System.Threading;
using System.Management;
using System.DirectoryServices;
using System.Collections;
using Microsoft.Win32;
using System.Runtime.InteropServices;
 
namespace ServiceInstaller
{
    [RunInstaller(true)]
    public partial class ServiceInstall : System.Configuration.Install.Installer
    { 
        public override void Install(IDictionary savedState)
        {
            base.Install(savedState);
            //Add custom code here
        }
        
        public override void Uninstall(IDictionary savedState)
        {
            base.Uninstall(savedState);
            //Add custom code here
        }
 
        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
            //Add custom code here
        }
 
        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
           //Add custom code here
        }
 
        static void Main()
        {
 
        }
    }
}         

Adding Custom Action to MSI project

Add a Setup and deployment project named SetupService in the same solution.

InstallService.png

LaunchService Method

This method explains how service is installed using Windows NT utilities instsrv.exe and srvany.exe.

private bool LaunchService(string serviceEXE)
{
    bool blnServiceInstalled = true;
 
    //Stop Service if running
    System.ServiceProcess.ServiceController[] services;
    services = System.ServiceProcess.ServiceController.GetServices();
    if (services != null)
    {
        for(int intServiceCount=0; intServiceCount<services.Length;intServiceCount++)
        {
            if(services[intServiceCount].ServiceName == serviceEXE)
            {
                if(services[intServiceCount].Status == ServiceControllerStatus.Running)
                {
                    using(StreamWriter sw = File.CreateText(strPath + batchFileName))
                    {
                        sw.WriteLine("net stop {0}", serviceEXE);
                    }
                    ExecuteBatchFile();
                    File.Delete(strPath + batchFileName);
                }
                break;
            }
        }
    }
 
   //Register as Windows Service using instsrv.exe and srvany.exe
   using (StreamWriter sw = File.CreateText(strPath + batchFileName))
   {
        sw.WriteLine("cd {0}", strPath);
        sw.WriteLine("instsrv " + serviceEXE + " " + strPath + "\\" + "srvany.exe");
        sw.Flush();
        sw.Close();
   }
   ExecuteBatchFile();
   File.Delete(strPath + batchFileName);
 
 
   //Modify Registry entries for service added
   RegistryKey SystemServicesKey =  
       Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Services");
   if (SystemServicesKey != null)
   {
        //Open service key with write access
        RegistryKey userServiceKey = SystemServicesKey.OpenSubKey(serviceEXE, true);
        if (userServiceKey != null)
        {
            userServiceKey.SetValue("Description", "Test Service Application");
            if (userName != "")
            {
                userServiceKey.SetValue("ObjectName", ".\\" + userName);
            }
            else
            {
                userServiceKey.SetValue("ObjectName", ServiceAccount.LocalSystem);
            }
            //Set path where service is copied on the system 
            userServiceKey.SetValue("ImagePath", strPath + "\\" +serviceEXE+serviceExtn);
 
            //Start automatically
            userServiceKey.SetValue("Start", 0x02);
 
            userServiceKey.Close();
            SystemServicesKey.Close();
        }
        else
        {
            SystemServicesKey.Close();
            MessageBox.Show("Windows Service registration failed.Installation aborted!");
            blnServiceInstalled = false;
        }
    }
    return blnServiceInstalled;
}

Key Points

Conclusion

Hope this code give an insight into writing custom actions and installing Windows service using Windows NT utilities. This is one of the possible methods for installing services. Since custom action is compiled as an executable, more customized code can be added in it.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralHow to set password for the configured Account Pin
tank_rakesh
1:50 28 Jul '08  
GeneralRe: How to set password for the configured Account Pin
lata07mahi
22:49 3 Aug '08  
GeneralWhy not just use what the .NET framework already provide? Pin
leppie
2:54 15 May '08  
GeneralRe: Why not just use what the .NET framework already provide? Pin
Martin Bohring
5:55 15 May '08  
GeneralRe: Why not just use what the .NET framework already provide? Pin
John Simmons / outlaw programmer
7:24 15 May '08  


Last Updated 15 May 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009