Skip to content

Instantly share code, notes, and snippets.

@morbidcamel101
Created November 24, 2014 15:58
Show Gist options
  • Save morbidcamel101/44e3329ff080785257e3 to your computer and use it in GitHub Desktop.
Save morbidcamel101/44e3329ff080785257e3 to your computer and use it in GitHub Desktop.
Service API Calls
using System;
using System.Runtime.InteropServices;
namespace Service
{
#region Service Installer
/// <summary>
/// Windows service installer helper class.
/// </summary>
/// <remarks>
/// This class contains logic to install a .NET based Windows service intelligently
/// without using "regsvcs" command line utility.
/// </remarks>
public sealed class ServiceInstallUtil
{
#region DLLImport
/// <summary>
/// Win32 API function to open the service manager programmatically. Located in Advapi32.dll.
/// </summary>
/// <param name="lpMachineName">Machine to open it on.</param>
/// <param name="lpSCDB">Service DB name.</param>
/// <param name="scParameter">Service Parameter (reserved).</param>
/// <returns></returns>
[DllImport("advapi32.dll")]
private static extern IntPtr OpenSCManager(string lpMachineName,string lpSCDB, int scParameter);
/// <summary>
/// Win32 API function to create a service programmatically. Located in Advapi32.dll.
/// </summary>
/// <param name="SC_HANDLE">Service handle.</param>
/// <param name="lpSvcName">Service name to create.</param>
/// <param name="lpDisplayName">Service Display name.</param>
/// <param name="dwDesiredAccess">Access permissions.</param>
/// <param name="dwServiceType">Type of service to create.</param>
/// <param name="dwStartType">Statup type for the service.</param>
/// <param name="dwErrorControl">Error control flags for the service.</param>
/// <param name="lpPathName">Path to the service.</param>
/// <param name="lpLoadOrderGroup">The load order group of the service.</param>
/// <param name="lpdwTagId">Tag (reserved).</param>
/// <param name="lpDependencies">Service dependencies.</param>
/// <param name="lpServiceStartName">Service startup name.</param>
/// <param name="lpPassword">Password (if any).</param>
/// <returns></returns>
[DllImport("Advapi32.dll")]
private 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);
/// <summary>
/// Win32 API function to close a service handle. Located in Advapi32.dll.
/// </summary>
/// <param name="SCHANDLE">Service handle to close.</param>
[DllImport("advapi32.dll")]
private static extern void CloseServiceHandle(IntPtr SCHANDLE);
/// <summary>
/// Win32 API function to start a service programmatically. Located in Advapi32.dll.
/// </summary>
/// <param name="SVHANDLE">Service handle to start.</param>
/// <param name="dwNumServiceArgs">Number of arguments specified in "lpServiceArgVectors"</param>
/// <param name="lpServiceArgVectors">Service startup arguments. Service specific.</param>
/// <returns>A word-bool (HRESULT) to indicate a successfull startup.</returns>
[DllImport("advapi32.dll")]
private static extern int StartService(IntPtr SVHANDLE,int dwNumServiceArgs,string lpServiceArgVectors);
/// <summary>
/// Win32 API function to open a service programmatically. Located in Advapi32.dll.
/// </summary>
/// <param name="SCHANDLE">Service handle to open.</param>
/// <param name="lpSvcName">Service name to open.</param>
/// <param name="dwNumServiceArgs">Number of service arguments. Service specific.</param>
/// <returns>A word-bool (HRESULT) to indicate if it's opened successfully</returns>
[DllImport("advapi32.dll",SetLastError=true)]
private static extern IntPtr OpenService(IntPtr SCHANDLE,string lpSvcName,int dwNumServiceArgs);
/// <summary>
/// Win32 API function to delete a service dynamically. Located in Advapi32.dll.
/// </summary>
/// <param name="SVHANDLE">Handle to the service to delete.</param>
/// <returns>A word-bool (HRESULT) to indicate successfull deletion.</returns>
[DllImport("advapi32.dll")]
private static extern int DeleteService(IntPtr SVHANDLE);
/// <summary>
/// Win32 API function to get the last error generated by a function that returns a HRESULT.
/// Located in kernel32.dll.
/// </summary>
/// <returns>A HRESULT value that indicates the last error.</returns>
[DllImport("kernel32.dll")]
private static extern int GetLastError();
#endregion DLLImport
/// <summary>
/// Install a .NET based Windows service.
/// </summary>
/// <param name="svcPath">Path to the exe that contains the service.</param>
/// <param name="svcName">The name of the service to install.</param>
/// <param name="svcDispName">Display name of the service.</param>
/// <returns>A boolean value indicating success or failure.</returns>
/// <remarks>
/// Developer Note: This class is used in the "IOInvoker.exe" .NET remoting service.
/// </remarks>
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_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("Successfully installed service " + svcDispName);
CloseServiceHandle(sc_handle);
return true;
}
}
else
Console.WriteLine("SCM not opened successfully");
return false;
}
catch(Exception e)
{
throw e;
}
}
/// <summary>
/// Uninstall a 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);
if(svc_hndl.ToInt32() !=0)
{
int i = DeleteService(svc_hndl);
if (i != 0)
{
CloseServiceHandle(sc_hndl);
Console.WriteLine("Service "+svcName+" uninstalled successfully.");
return true;
}
else
{
CloseServiceHandle(sc_hndl);
return false;
}
}
else
return false;
}
else
return false;
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment