Ansel's Blog

It would probably render the application more complex

博客园 首页 新随笔 联系 订阅 管理

Installing a Service Programmatically
Author Date Of Submission User Level
Sachin Nigam 09/04/2003 Intermediate
 
 
With the arrival of .Net, creation of a windows service has become a piece of cake by just selecting Windows Service as project type in the New Project Dialog Box. For installing a service, .Net provides a utility called installutil.exe which installs the service and registers it with Service Control Manager(SCM) but at times there is a need to install the service programmatically for example as a part of your custom installer program where you don't want your user to manually install the service using installutil.
The following piece of code shows how to install/uninstall a given service and register it with SCM calling appropriate APIs using P/Invoke in C#

 
SERVICEINSTALLER.CS
 

using System;
using System.Runtime.InteropServices;
 
namespace SvcInstaller
{
 
/// <summary>
 
/// Summary description for ServiceInstaller.
 
/// </summary>

 class ServiceInstaller
 
{
  
#region Private Variables
  
  
private string _servicePath;
  
private string _serviceName;
  
private string _serviceDisplayName;
 
  
#endregion
 Private Variables
 
  
#region DLLImport
  
  [DllImport(
"advapi32.dll")]
  
public static extern IntPtr OpenSCManager(string lpMachineName,string lpSCDB, int scParameter);
  [DllImport(
"Advapi32.dll")]
  
public static extern IntPtr CreateService(IntPtr SC_HANDLE,string lpSvcName,string lpDisplayName, 
 
int dwDesiredAccess,int dwServiceType,int dwStartType,int dwErrorControl,string lpPathName, 
string lpLoadOrderGroup,int lpdwTagId,string lpDependencies,string lpServiceStartName,string lpPassword);
  [DllImport(
"advapi32.dll")]
  
public static extern void CloseServiceHandle(IntPtr SCHANDLE);
  [DllImport(
"advapi32.dll")]
  
public static extern int StartService(IntPtr SVHANDLE,int dwNumServiceArgs,string lpServiceArgVectors);
  
  [DllImport(
"advapi32.dll",SetLastError=true)]
  
public static extern IntPtr OpenService(IntPtr SCHANDLE,string lpSvcName,int dwNumServiceArgs);
  [DllImport(
"advapi32.dll")]
  
public static extern int DeleteService(IntPtr SVHANDLE);
 
  [DllImport(
"kernel32.dll")]
  
public static extern int GetLastError();
  
  
#endregion
 DLLImport
 
  
  
/// <summary>
  
/// The main entry point for the application.
  
/// </summary>

  #region Main method + testing code 
   [STAThread]
   
static void Main(string[] args)
   
{
     
     
// TODO: Add code to start application here
     
    
    
#region Testing
    
//  Testing --------------
     string svcPath;
     
string svcName;
     
string svcDispName;
     
     
//path to the service that you want to install
     svcPath = @"C:\build\service\Debug\Service.exe";
     svcDispName
="Service Display Name";
     svcName
= "Service Name";
  
     ServiceInstaller c 
= new ServiceInstaller();
     c.InstallService(svcPath, svcName, svcDispName);
  
     Console.Read();
       Testing 
--------------
    
#endregion
 Testing
   }

  
#endregion
 Main method + testing code - Commented
 

  
  
/// <summary>
  
/// This method installs and runs the service in the service conrol manager.
  
/// </summary>
  
/// <param name="svcPath">The complete path of the service.</param>
  
/// <param name="svcName">Name of the service.</param>
  
/// <param name="svcDispName">Display name of the service.</param>
  
/// <returns>True if the process went thro successfully. False if there was any error.</returns>

  public bool InstallService(string svcPath, string svcName, string svcDispName)
  
{
   
#region Constants declaration.
   
int SC_MANAGER_CREATE_SERVICE = 0x0002;
   
int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
   
//int SERVICE_DEMAND_START = 0x00000003;
   int SERVICE_ERROR_NORMAL = 0x00000001;
 
   
int STANDARD_RIGHTS_REQUIRED = 0xF0000;
   
int SERVICE_QUERY_CONFIG       =    0x0001;
   
int SERVICE_CHANGE_CONFIG       =   0x0002;
   
int SERVICE_QUERY_STATUS           =  0x0004;
   
int SERVICE_ENUMERATE_DEPENDENTS   = 0x0008;
   
int SERVICE_START                  =0x0010;
   
int SERVICE_STOP                   =0x0020;
   
int SERVICE_PAUSE_CONTINUE         =0x0040;
   
int SERVICE_INTERROGATE            =0x0080;
   
int SERVICE_USER_DEFINED_CONTROL   =0x0100;
 
   
int SERVICE_ALL_ACCESS             =  (STANDARD_RIGHTS_REQUIRED     | 
        SERVICE_QUERY_CONFIG         
|
        SERVICE_CHANGE_CONFIG        
|
        SERVICE_QUERY_STATUS         
| 
        SERVICE_ENUMERATE_DEPENDENTS 
| 
        SERVICE_START                
| 
        SERVICE_STOP                 
| 
        SERVICE_PAUSE_CONTINUE       
| 
        SERVICE_INTERROGATE          
| 
        SERVICE_USER_DEFINED_CONTROL);
   
int SERVICE_AUTO_START = 0x00000002;
   
#endregion
 Constants declaration.
 
   
try
   
{
    IntPtr  sc_handle 
= OpenSCManager(null,null,SC_MANAGER_CREATE_SERVICE);
 
    
if (sc_handle.ToInt32() != 0)
    
{
     IntPtr sv_handle 
= CreateService(sc_handle,svcName,svcDispName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,svcPath,null,0,null,null,null);
 
     
if(sv_handle.ToInt32() ==0)
     
{
 
      CloseServiceHandle(sc_handle);
      
return false;
     }

     
else
     
{
      
//now trying to start the service
      int i = StartService(sv_handle,0,null);
      
// If the value i is zero, then there was an error starting the service.
      
// note: error may arise if the service is already running or some other problem.
      if(i==0)
      
{
       
//Console.WriteLine("Couldnt start service");
       return false;
      }

      
//Console.WriteLine("Success");
      CloseServiceHandle(sc_handle);
      
return true;
     }

    }

    
else
     
//Console.WriteLine("SCM not opened successfully");
     return false;
 
   }

   
catch(Exception e)
   
{
    
throw e;
   }

  }

 
  
  
/// <summary>
  
/// This method uninstalls the service from the service conrol manager.
  
/// </summary>
  
/// <param name="svcName">Name of the service to uninstall.</param>

  public bool UnInstallService(string svcName)
  
{
   
int GENERIC_WRITE = 0x40000000;
   IntPtr sc_hndl 
= OpenSCManager(null,null,GENERIC_WRITE);
 
   
if(sc_hndl.ToInt32() !=0)
   
{
    
int DELETE = 0x10000;
    IntPtr svc_hndl 
= OpenService(sc_hndl,svcName,DELETE);
    
//Console.WriteLine(svc_hndl.ToInt32());
    if(svc_hndl.ToInt32() !=0)
    

     
int i = DeleteService(svc_hndl);
     
if (i != 0)
     
{
      CloseServiceHandle(sc_hndl);
      
return true;
     }

     
else
     
{
      CloseServiceHandle(sc_hndl);
      
return false;
     }

    }

    
else
     
return false;
   }

   
else
    
return false;
  }

 }

}


 

The above code shows that installing a service programmatically is as simple if not simpler than using installutil and gives you far more flexibility.

posted on 2005-08-23 23:22  Ansel  阅读(393)  评论(0编辑  收藏  举报