如何在 C # 中以编程方式安装 Windows 服务?

我有3个项目在我的 VS 解决方案。其中一个是 Web 应用程序,第二个是 Windows 服务,最后一个是 Web 应用程序的安装项目。

我想要的是在我的安装项目的网络应用程序的安装结束,在我的自定义操作尝试和安装我的 Windows 服务,因为我有在那时的位置组装。

104377 次浏览

Please have a look at this article.


Sometimes you may want to install a Windows Service programmatically, but the target machine does not have InstallUtil.exe.

Add a reference to System.Configuration.Install

Use the code below.

Note that the exeFileName is the InstallerClass .exe and not the ServiceClass .exe.

public static void InstallService(string exeFilename)
{
string[] commandLineOptions = new string[1] { "/LogFile=install.log" };


System.Configuration.Install.AssemblyInstaller installer = new System.Configuration.Install.AssemblyInstaller(exeFilename, commandLineOptions);


installer.UseNewContext = true;
installer.Install(null);
installer.Commit(null);


}

To uninstall:

public static void UninstallService(string exeFilename)
{
string[] commandLineOptions = new string[1] { "/LogFile=uninstall.log" };


System.Configuration.Install.AssemblyInstaller installer = new System.Configuration.Install.AssemblyInstaller(exeFilename, commandLineOptions);


installer.UseNewContext = true;
installer.Uninstall(null);


}

Ok, here is what REALLY worked for me, it has been tested on multiple machines with different OS ( Vista, XP, Win2k, Win2003 server )

The code has been taken from here so full credit goes to whoever wrote this piece of code.

Once you add the dll or source file into your project make sure to add the ServiceTools namespace and then you have access to some very handy functionality such as...

//Installs and starts the service
ServiceInstaller.InstallAndStart("MyServiceName", "MyServiceDisplayName", "C:\\PathToServiceFile.exe");


//Removes the service
ServiceInstaller.Uninstall("MyServiceName");


//Checks the status of the service
ServiceInstaller.GetServiceStatus("MyServiceName");


//Starts the service
ServiceInstaller.StartService("MyServiceName");


//Stops the service
ServiceInstaller.StopService("MyServiceName");


//Check if service is installed
ServiceInstaller.ServiceIsInstalled("MyServiceName");

I hope this helps.

I found several errors in the code that you reused and have fixed these and also cleaned it up a little. Again, the original code is taken from here.

public static class ServiceInstaller
{
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;


[StructLayout(LayoutKind.Sequential)]
private class SERVICE_STATUS
{
public int dwServiceType = 0;
public ServiceState dwCurrentState = 0;
public int dwControlsAccepted = 0;
public int dwWin32ExitCode = 0;
public int dwServiceSpecificExitCode = 0;
public int dwCheckPoint = 0;
public int dwWaitHint = 0;
}


#region OpenSCManager
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr OpenSCManager(string machineName, string databaseName, ScmAccessRights dwDesiredAccess);
#endregion


#region OpenService
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceAccessRights dwDesiredAccess);
#endregion


#region CreateService
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceAccessRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword);
#endregion


#region CloseServiceHandle
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseServiceHandle(IntPtr hSCObject);
#endregion


#region QueryServiceStatus
[DllImport("advapi32.dll")]
private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus);
#endregion


#region DeleteService
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteService(IntPtr hService);
#endregion


#region ControlService
[DllImport("advapi32.dll")]
private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus);
#endregion


#region StartService
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors);
#endregion


public static void Uninstall(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);
if (service == IntPtr.Zero)
throw new ApplicationException("Service not installed.");


try
{
StopService(service);
if (!DeleteService(service))
throw new ApplicationException("Could not delete service " + Marshal.GetLastWin32Error());
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static bool ServiceIsInstalled(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);


if (service == IntPtr.Zero)
return false;


CloseServiceHandle(service);
return true;
}
finally
{
CloseServiceHandle(scm);
}
}


public static void InstallAndStart(string serviceName, string displayName, string fileName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);


if (service == IntPtr.Zero)
service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, ServiceBootFlag.AutoStart, ServiceError.Normal, fileName, null, IntPtr.Zero, null, null, null);


if (service == IntPtr.Zero)
throw new ApplicationException("Failed to install service.");


try
{
StartService(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static void StartService(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Start);
if (service == IntPtr.Zero)
throw new ApplicationException("Could not open service.");


try
{
StartService(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static void StopService(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Stop);
if (service == IntPtr.Zero)
throw new ApplicationException("Could not open service.");


try
{
StopService(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


private static void StartService(IntPtr service)
{
SERVICE_STATUS status = new SERVICE_STATUS();
StartService(service, 0, 0);
var changedStatus = WaitForServiceStatus(service, ServiceState.StartPending, ServiceState.Running);
if (!changedStatus)
throw new ApplicationException("Unable to start service");
}


private static void StopService(IntPtr service)
{
SERVICE_STATUS status = new SERVICE_STATUS();
ControlService(service, ServiceControl.Stop, status);
var changedStatus = WaitForServiceStatus(service, ServiceState.StopPending, ServiceState.Stopped);
if (!changedStatus)
throw new ApplicationException("Unable to stop service");
}


public static ServiceState GetServiceStatus(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);
if (service == IntPtr.Zero)
return ServiceState.NotFound;


try
{
return GetServiceStatus(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


private static ServiceState GetServiceStatus(IntPtr service)
{
SERVICE_STATUS status = new SERVICE_STATUS();


if (QueryServiceStatus(service, status) == 0)
throw new ApplicationException("Failed to query service status.");


return status.dwCurrentState;
}


private static bool WaitForServiceStatus(IntPtr service, ServiceState waitStatus, ServiceState desiredStatus)
{
SERVICE_STATUS status = new SERVICE_STATUS();


QueryServiceStatus(service, status);
if (status.dwCurrentState == desiredStatus) return true;


int dwStartTickCount = Environment.TickCount;
int dwOldCheckPoint = status.dwCheckPoint;


while (status.dwCurrentState == waitStatus)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.


int dwWaitTime = status.dwWaitHint / 10;


if (dwWaitTime < 1000) dwWaitTime = 1000;
else if (dwWaitTime > 10000) dwWaitTime = 10000;


Thread.Sleep(dwWaitTime);


// Check the status again.


if (QueryServiceStatus(service, status) == 0) break;


if (status.dwCheckPoint > dwOldCheckPoint)
{
// The service is making progress.
dwStartTickCount = Environment.TickCount;
dwOldCheckPoint = status.dwCheckPoint;
}
else
{
if (Environment.TickCount - dwStartTickCount > status.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
return (status.dwCurrentState == desiredStatus);
}


private static IntPtr OpenSCManager(ScmAccessRights rights)
{
IntPtr scm = OpenSCManager(null, null, rights);
if (scm == IntPtr.Zero)
throw new ApplicationException("Could not connect to service control manager.");


return scm;
}
}




public enum ServiceState
{
Unknown = -1, // The state cannot be (has not been) retrieved.
NotFound = 0, // The service is not known on the host server.
Stopped = 1,
StartPending = 2,
StopPending = 3,
Running = 4,
ContinuePending = 5,
PausePending = 6,
Paused = 7
}


[Flags]
public enum ScmAccessRights
{
Connect = 0x0001,
CreateService = 0x0002,
EnumerateService = 0x0004,
Lock = 0x0008,
QueryLockStatus = 0x0010,
ModifyBootConfig = 0x0020,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | Connect | CreateService |
EnumerateService | Lock | QueryLockStatus | ModifyBootConfig)
}


[Flags]
public enum ServiceAccessRights
{
QueryConfig = 0x1,
ChangeConfig = 0x2,
QueryStatus = 0x4,
EnumerateDependants = 0x8,
Start = 0x10,
Stop = 0x20,
PauseContinue = 0x40,
Interrogate = 0x80,
UserDefinedControl = 0x100,
Delete = 0x00010000,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig |
QueryStatus | EnumerateDependants | Start | Stop | PauseContinue |
Interrogate | UserDefinedControl)
}


public enum ServiceBootFlag
{
Start = 0x00000000,
SystemStart = 0x00000001,
AutoStart = 0x00000002,
DemandStart = 0x00000003,
Disabled = 0x00000004
}


public enum ServiceControl
{
Stop = 0x00000001,
Pause = 0x00000002,
Continue = 0x00000003,
Interrogate = 0x00000004,
Shutdown = 0x00000005,
ParamChange = 0x00000006,
NetBindAdd = 0x00000007,
NetBindRemove = 0x00000008,
NetBindEnable = 0x00000009,
NetBindDisable = 0x0000000A
}


public enum ServiceError
{
Ignore = 0x00000000,
Normal = 0x00000001,
Severe = 0x00000002,
Critical = 0x00000003
}

Please let me know if anyone finds anything wrong with this code!

By using the Topshelf project you can install by calling your executable:

MyService.exe install

Topshelf also takes care of other Windows Service plumbing.

After creating an instance of an installer class for my service (very basic) all I had to do is to call :

ManagedInstallerClass.InstallHelper(new string[] {
Assembly.GetExecutingAssembly().Location });

to install it and

ManagedInstallerClass.InstallHelper(new string[] { "/u",
Assembly.GetExecutingAssembly().Location });

to uninstall the service. The calling code is, here, in the same assembly as the service executable.

to get the service to install through command line all I had to do is to connect this to the executable though command line arguments and test for System.Environment.UserInteractive to know if it is the service executing or someone trying to install-uninstall it and voila... no funky interop stuff... no pointers leaking...

Total about 20 lines of code spread over two classes did the trick.

to replace InstallUtil just take a look at ManagedInstallerClass.InstallHelper

In this article I read all posts and comments Bu still I don't know How can I set Account Type and StartType method when I gonna add windows service. This code example works fine my side its just add a service own local system) But I prepare Setup program I must think StartMode and User Account Type method because of customers system.
there is every appearance that ServiceBootFlag enum provide StartType but Account Type still a problem.

    [DllImport("advapi32.dll", EntryPoint = "CreateServiceA")]


private static extern IntPtr CreateService(IntPtr hSCManager, string


lpServiceName, string lpDisplayName, ServiceRights dwDesiredAccess, int


dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl,


string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string


lpDependencies, string lp, string lpPassword);

Since I was faced with the challenge to install services programmatically which run under a certain user. I extended the InstallAndStart method to make use of lp and lpPassword...

Not much but might help.

public static void InstallAndStart(
string serviceName,
string displayName,
string fileName,
string username,
string password)
{
IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);


try
{
IntPtr service = OpenService(
scm,
serviceName,
ServiceAccessRights.AllAccess);


if (service == IntPtr.Zero)
service = CreateService(
scm,
serviceName,
displayName,
ServiceAccessRights.AllAccess,
SERVICE_WIN32_OWN_PROCESS,
ServiceBootFlag.AutoStart,
ServiceError.Normal,
fileName,
null,
IntPtr.Zero,
null,
username,
password);


if (service == IntPtr.Zero)
throw new ApplicationException("Failed to install service.");


try
{
StartService(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}

Use below code to install windows service using C#:

public void InstallWinService(string winServicePath)
{
try
{
ManagedInstallerClass.InstallHelper(new string[] { winServicePath});
}
catch (Exception)
{


throw;
}
}

I used Lars answer to manage my service and it works fine. But I needed to pass arguments to service and it took me a couple of hours to find out how to do it. So I decided to post altered class with ability to start service with parameters:

    public static class ServiceHelper
{
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;


[StructLayout(LayoutKind.Sequential)]
private class SERVICE_STATUS
{
public int dwServiceType = 0;
public ServiceState dwCurrentState = 0;
public int dwControlsAccepted = 0;
public int dwWin32ExitCode = 0;
public int dwServiceSpecificExitCode = 0;
public int dwCheckPoint = 0;
public int dwWaitHint = 0;
}


#region OpenSCManager
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr OpenSCManager(string machineName, string databaseName, ScmAccessRights dwDesiredAccess);
#endregion


#region OpenService
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceAccessRights dwDesiredAccess);
#endregion


#region CreateService
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceAccessRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword);
#endregion


#region CloseServiceHandle
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseServiceHandle(IntPtr hSCObject);
#endregion


#region QueryServiceStatus
[DllImport("advapi32.dll")]
private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus);
#endregion


#region DeleteService
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteService(IntPtr hService);
#endregion


#region ControlService
[DllImport("advapi32.dll")]
private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus);
#endregion


#region StartService
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int StartService(IntPtr hService, int dwNumServiceArgs, string[] lpServiceArgVectors);
#endregion


public static void Uninstall(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);
if (service == IntPtr.Zero)
throw new ApplicationException("Service not installed.");


try
{
StopService(service);
if (!DeleteService(service))
throw new ApplicationException("Could not delete service " + Marshal.GetLastWin32Error());
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static bool ServiceIsInstalled(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);


if (service == IntPtr.Zero)
return false;


CloseServiceHandle(service);
return true;
}
finally
{
CloseServiceHandle(scm);
}
}


public static void InstallAndStart(string serviceName, string displayName, string fileName,string[] args)
{
IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);


if (service == IntPtr.Zero)
service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, ServiceBootFlag.AutoStart, ServiceError.Normal, fileName, null, IntPtr.Zero, null, null, null);


if (service == IntPtr.Zero)
throw new ApplicationException("Failed to install service.");


try
{
StartService(service,args);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static void StartService(string serviceName,string[] args)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Start);
if (service == IntPtr.Zero)
throw new ApplicationException("Could not open service.");


try
{
StartService(service,args);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


public static void StopService(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus | ServiceAccessRights.Stop);
if (service == IntPtr.Zero)
throw new ApplicationException("Could not open service.");


try
{
StopService(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


private static void StartService(IntPtr service,string[] args)
{
SERVICE_STATUS status = new SERVICE_STATUS();
StartService(service, args.Length, args);
var changedStatus = WaitForServiceStatus(service, ServiceState.StartPending, ServiceState.Running);
if (!changedStatus)
throw new ApplicationException("Unable to start service");
}


private static void StopService(IntPtr service)
{
SERVICE_STATUS status = new SERVICE_STATUS();
ControlService(service, ServiceControl.Stop, status);
var changedStatus = WaitForServiceStatus(service, ServiceState.StopPending, ServiceState.Stopped);
if (!changedStatus)
throw new ApplicationException("Unable to stop service");
}


public static ServiceState GetServiceStatus(string serviceName)
{
IntPtr scm = OpenSCManager(ScmAccessRights.Connect);


try
{
IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus);
if (service == IntPtr.Zero)
return ServiceState.NotFound;


try
{
return GetServiceStatus(service);
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scm);
}
}


private static ServiceState GetServiceStatus(IntPtr service)
{
SERVICE_STATUS status = new SERVICE_STATUS();


if (QueryServiceStatus(service, status) == 0)
throw new ApplicationException("Failed to query service status.");


return status.dwCurrentState;
}


private static bool WaitForServiceStatus(IntPtr service, ServiceState waitStatus, ServiceState desiredStatus)
{
SERVICE_STATUS status = new SERVICE_STATUS();


QueryServiceStatus(service, status);
if (status.dwCurrentState == desiredStatus) return true;


int dwStartTickCount = Environment.TickCount;
int dwOldCheckPoint = status.dwCheckPoint;


while (status.dwCurrentState == waitStatus)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.


int dwWaitTime = status.dwWaitHint / 10;


if (dwWaitTime < 1000) dwWaitTime = 1000;
else if (dwWaitTime > 10000) dwWaitTime = 10000;


Thread.Sleep(dwWaitTime);


// Check the status again.


if (QueryServiceStatus(service, status) == 0) break;


if (status.dwCheckPoint > dwOldCheckPoint)
{
// The service is making progress.
dwStartTickCount = Environment.TickCount;
dwOldCheckPoint = status.dwCheckPoint;
}
else
{
if (Environment.TickCount - dwStartTickCount > status.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
return (status.dwCurrentState == desiredStatus);
}


private static IntPtr OpenSCManager(ScmAccessRights rights)
{
IntPtr scm = OpenSCManager(null, null, rights);
if (scm == IntPtr.Zero)
throw new ApplicationException("Could not connect to service control manager.");


return scm;
}
}




public enum ServiceState
{
Unknown = -1, // The state cannot be (has not been) retrieved.
NotFound = 0, // The service is not known on the host server.
Stopped = 1,
StartPending = 2,
StopPending = 3,
Running = 4,
ContinuePending = 5,
PausePending = 6,
Paused = 7
}


[Flags]
public enum ScmAccessRights
{
Connect = 0x0001,
CreateService = 0x0002,
EnumerateService = 0x0004,
Lock = 0x0008,
QueryLockStatus = 0x0010,
ModifyBootConfig = 0x0020,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | Connect | CreateService |
EnumerateService | Lock | QueryLockStatus | ModifyBootConfig)
}


[Flags]
public enum ServiceAccessRights
{
QueryConfig = 0x1,
ChangeConfig = 0x2,
QueryStatus = 0x4,
EnumerateDependants = 0x8,
Start = 0x10,
Stop = 0x20,
PauseContinue = 0x40,
Interrogate = 0x80,
UserDefinedControl = 0x100,
Delete = 0x00010000,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig |
QueryStatus | EnumerateDependants | Start | Stop | PauseContinue |
Interrogate | UserDefinedControl)
}


public enum ServiceBootFlag
{
Start = 0x00000000,
SystemStart = 0x00000001,
AutoStart = 0x00000002,
DemandStart = 0x00000003,
Disabled = 0x00000004
}


public enum ServiceControl
{
Stop = 0x00000001,
Pause = 0x00000002,
Continue = 0x00000003,
Interrogate = 0x00000004,
Shutdown = 0x00000005,
ParamChange = 0x00000006,
NetBindAdd = 0x00000007,
NetBindRemove = 0x00000008,
NetBindEnable = 0x00000009,
NetBindDisable = 0x0000000A
}


public enum ServiceError
{
Ignore = 0x00000000,
Normal = 0x00000001,
Severe = 0x00000002,
Critical = 0x00000003
}

Another method could be using SC.exe from command prompt:

 System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C sc create MyService binpath=\"c:\\...\\MyService.exe\"";
process.StartInfo = startInfo;
process.Start();