I want to write a console or Click Once WinForms app that will programmatically stop and/or start a windows service on a remote box.
我想编写一个控制台或Click Once WinForms应用程序,它将以编程方式停止和/或启动远程盒子上的Windows服务。
Both boxes are running .NET 3.5 - what .NET API's are available to accomplish this?
这两个盒子都运行.NET 3.5 - 有哪些.NET API可以实现这一目标?
9 个解决方案
#1
in C#:
var sc = new System.ServiceProcess.ServiceController("MyService", "MyRemoteMachine");
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
#2
You can also do this from a command console using the sc
command:
您也可以使用sc命令从命令控制台执行此操作:
sc <server> start [service name]
sc <server> stop [service name]
Use
sc <server> query | find "SERVICE_NAME"
to get a list of service names.
获取服务名称列表。
The option <server>
has the form \\ServerName
选项
Example
sc \\MyServer stop schedule
will stop the Scheduler service.
sc \\ MyServer停止计划将停止计划程序服务。
#3
You need to have permission to administer the services on the remote box.
您需要拥有管理远程服务器上的服务的权限。
As Mehrdad says, you can also use WMI. Both methods work for start and stop, but WMI requires more coding and will give you more access to other resources
正如Mehrdad所说,你也可以使用WMI。这两种方法都适用于启动和停止,但WMI需要更多编码,并且可以为您提供更多访问其他资源的权限
#4
If you don't want to code it yourself, PsService by Microsoft/Sysinternals is a command line tool that does what you want.
如果您不想自己编写代码,Microsoft / Sysinternals的PsService是一个命令行工具,可以执行您想要的操作。
#5
You can use System.Management
APIs (WMI) to control services remotely. WMI is the generic API to do administrative tasks.
您可以使用System.Management API(WMI)远程控制服务。 WMI是执行管理任务的通用API。
For this problem, however, I suggest you to use the easier to use System.ServiceProcess.ServiceController
class.
但是,对于这个问题,我建议您使用更容易使用的System.ServiceProcess.ServiceController类。
#6
if you need to get the name of the Service:
如果您需要获取服务的名称:
run this from the command line:
从命令行运行:
sc query
You will see for example, that SQL Server's service name is 'MSSQL$SQLEXPRESS'.
例如,您将看到SQL Server的服务名称为“MSSQL $ SQLEXPRESS”。
So to stop the SQL Server service in C#:
所以要在C#中停止SQL Server服务:
ServiceController controller = new ServiceController();
controller.MachineName = "Machine1";
controller.ServiceName = "MSSQL$SQLEXPRESS";
if(controller.Status == ServiceControllerStatus.Running)
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
#7
galets code snippet above is a great start. However, keep in mind it assumes that the service has already started, or, more importantly, that
上面的galets代码片段是一个很好的开始。但是,请记住,它假设服务已经开始,或者更重要的是,它已经开始
sc.Status == System.ServiceProcess.ServiceControllerStatus.Running
Also, it may important to, at some point during code execution, call
此外,在代码执行期间的某些时候调用也很重要
sc.Refresh();
because the properties values (such as ServiceControllerStatus) may not reflect the actual properties of the service. For instance, you may call
因为属性值(例如ServiceControllerStatus)可能无法反映服务的实际属性。例如,你可以打电话
sc.Start();
and wait indefinitely when this command executes
并且在执行此命令时无限期地等待
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running)
Here is a version of this code that I coded with those considerations in mind.
以下是此代码的一个版本,我在编写时考虑了这些注意事项。
//Restart Content Service on DEV.
String svcName = "TheServiceName";
String machineName = "TheMachineName";
var sc = new System.ServiceProcess.ServiceController(svcName, machineName);
Console.WriteLine("Stopping Service '{0}' on machine '{1}", svcName, machineName);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
//sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
do
{
try
{
sc.Refresh();
if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
Console.WriteLine("Code has detected that servive start is pending, waiting 5 seconds to see if status changes..");
System.Threading.Thread.Sleep(5000);
}
else
{
Console.WriteLine("waiting 5 seconds and retrying start..");
System.Threading.Thread.Sleep(5000);
Console.WriteLine("Attempt Starting Service '{0}' on machine '{1}", svcName, machineName);
sc.Start();
}
}
catch(Exception ex)
{
//If it is already running, then abort do while
if (ex.InnerException.Message == "An instance of the service is already running")
{
Console.WriteLine(ex.InnerException.Message);
continue;
}
Console.WriteLine(ex.InnerException.ToString());
}
} while (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running);
#8
I Have done like below:
我做了如下:
Note:
- If you did't start your service if you are trying to stop it will throw exception.
- If you configure these things in your web.config ,configuration related exception will not come. No need to do anything in IIS.
如果您在尝试停止时未启动服务,则会抛出异常。
如果在web.config中配置这些内容,则不会出现与配置相关的异常。无需在IIS中执行任何操作。
In Web.Config
under <configuration>
在
<appSettings>
<add key="ServiceName" value="YourServiceName" />
<add key="MachineName" value="YourMachineName" />
</appSettings>
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true" userName="YourUserName" password="YourPassword"/>
</system.web>
In My Service Class:
在我的服务类中:
private void RestartService()
{
string serviceName = System.Configuration.ConfigurationSettings.AppSettings["ServiceName"];
string machineName = System.Configuration.ConfigurationSettings.AppSettings["MachineName"];
try
{
var service = new ServiceController(serviceName);
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
}
catch (Exception)
{
}
}
Hope this Helps.,
希望这可以帮助。,
#9
Here is a ServiceExtension that can Start and Stop Services on remote pc's.
这是一个可以在远程PC上启动和停止服务的ServiceExtension。
And it can set the Startup type of the service, even to "automatic (delayed)"
它可以设置服务的启动类型,甚至可以设置为“自动(延迟)”
modified version from this Answer to work on remote machines.
本答案中的修改版本可以在远程计算机上运行。
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.ServiceProcess;
namespace Helpers
{
public enum ServiceStartModeEx
{
Automatic = 2,
Manual = 3,
Disabled = 4,
DelayedAutomatic = 99
}
/// <summary>
/// Extensions to the ServiceController class.
/// </summary>
public static class ServiceControlerExtensions
{
/// <summary>
/// Set the start mode for the service.
/// </summary>
/// <param name="serviceController">The service controller.</param>
/// <param name="mode">The desired start mode.</param>
public static void SetStartMode(this ServiceController serviceController, ServiceStartModeEx mode)
{
IntPtr serviceManagerHandle = OpenServiceManagerHandle(serviceController);
IntPtr serviceHandle = OpenServiceHandle(serviceController, serviceManagerHandle);
try
{
if (mode == ServiceStartModeEx.DelayedAutomatic)
{
ChangeServiceStartType(serviceHandle, ServiceStartModeEx.Automatic);
ChangeDelayedAutoStart(serviceHandle, true);
}
else
{
// Delayed auto-start overrides other settings, so it must be set first.
ChangeDelayedAutoStart(serviceHandle, false);
ChangeServiceStartType(serviceHandle, mode);
}
}
finally
{
if (serviceHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceHandle);
}
if (serviceManagerHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceManagerHandle);
}
}
}
private static IntPtr OpenServiceHandle(ServiceController serviceController, IntPtr serviceManagerHandle)
{
var serviceHandle = OpenService(
serviceManagerHandle,
serviceController.ServiceName,
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
if (serviceHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Error");
}
return serviceHandle;
}
private static IntPtr OpenServiceManagerHandle(ServiceController serviceController)
{
var machineName = string.IsNullOrWhiteSpace(serviceController.MachineName)
? null
: serviceController.MachineName;
IntPtr serviceManagerHandle = OpenSCManager(machineName, null, SC_MANAGER_ALL_ACCESS);
if (serviceManagerHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Manager Error");
}
return serviceManagerHandle;
}
private static void ChangeServiceStartType(IntPtr serviceHandle, ServiceStartModeEx mode)
{
bool result = ChangeServiceConfig(
serviceHandle,
SERVICE_NO_CHANGE,
(uint)mode,
SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
null,
null,
null);
if (result == false)
{
ThrowLastWin32Error("Could not change service start type");
}
}
private static void ChangeDelayedAutoStart(IntPtr hService, bool delayed)
{
// Create structure that contains DelayedAutoStart property.
SERVICE_DELAYED_AUTO_START_INFO info = new SERVICE_DELAYED_AUTO_START_INFO();
// Set the DelayedAutostart property in that structure.
info.fDelayedAutostart = delayed;
// Allocate necessary memory.
IntPtr hInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_DELAYED_AUTO_START_INFO)));
// Convert structure to pointer.
Marshal.StructureToPtr(info, hInfo, true);
// Change the configuration.
bool result = ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, hInfo);
// Release memory.
Marshal.FreeHGlobal(hInfo);
if (result == false)
{
ThrowLastWin32Error("Could not set service to delayed automatic");
}
}
private static void ThrowLastWin32Error(string messagePrefix)
{
int nError = Marshal.GetLastWin32Error();
var win32Exception = new Win32Exception(nError);
string message = string.Format("{0}: {1}", messagePrefix, win32Exception.Message);
throw new ExternalException(message);
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr OpenService(
IntPtr hSCManager,
string lpServiceName,
uint dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
SetLastError = true)]
private static extern IntPtr OpenSCManager(
string machineName,
string databaseName,
uint dwAccess);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern Boolean ChangeServiceConfig(
IntPtr hService,
UInt32 nServiceType,
UInt32 nStartType,
UInt32 nErrorControl,
String lpBinaryPathName,
String lpLoadOrderGroup,
IntPtr lpdwTagId,
[In] char[] lpDependencies,
String lpServiceStartName,
String lpPassword,
String lpDisplayName);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ChangeServiceConfig2(
IntPtr hService,
int dwInfoLevel,
IntPtr lpInfo);
[DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
private static extern int CloseServiceHandle(IntPtr hSCObject);
private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
private const uint SERVICE_QUERY_CONFIG = 0x00000001;
private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SERVICE_DELAYED_AUTO_START_INFO
{
public bool fDelayedAutostart;
}
}
}
You can start a service like this
你可以开始这样的服务
using System.ServiceProcess;
serviceName = "the name of the service"
serviceName =“服务名称”
machineName = "the name of the remote/local host"
machineName =“远程/本地主机的名称”
var service = new ServiceController(serviceName, machineName);
try
{
service.SetStartMode(ServiceStartModeEx.DelayedAutomatic);
service.Start();
}
finally
{
service.Close();
}
You can stop a service like this
你可以停止这样的服务
var service = new ServiceController(serviceName, machineName);
try
{
if (service.CanStop)
{
service.SetStartMode(ServiceStartModeEx.Disabled);
service.Stop();
}
}
finally
{
service.Close();
}
To grant a user rights to start and stop a service on a remote pc you have to set some service rights, you can google what subinacl.exe is and where to download it.
要授予用户在远程PC上启动和停止服务的权限,您必须设置一些服务权限,您可以google subinacl.exe是什么以及在何处下载它。
C:\Program Files (x86)\Windows Resource Kits\Tools>subinacl.exe /service SERVICENAME /grant=MACHINENAME\USERNAME=F
#1
in C#:
var sc = new System.ServiceProcess.ServiceController("MyService", "MyRemoteMachine");
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
#2
You can also do this from a command console using the sc
command:
您也可以使用sc命令从命令控制台执行此操作:
sc <server> start [service name]
sc <server> stop [service name]
Use
sc <server> query | find "SERVICE_NAME"
to get a list of service names.
获取服务名称列表。
The option <server>
has the form \\ServerName
选项
Example
sc \\MyServer stop schedule
will stop the Scheduler service.
sc \\ MyServer停止计划将停止计划程序服务。
#3
You need to have permission to administer the services on the remote box.
您需要拥有管理远程服务器上的服务的权限。
As Mehrdad says, you can also use WMI. Both methods work for start and stop, but WMI requires more coding and will give you more access to other resources
正如Mehrdad所说,你也可以使用WMI。这两种方法都适用于启动和停止,但WMI需要更多编码,并且可以为您提供更多访问其他资源的权限
#4
If you don't want to code it yourself, PsService by Microsoft/Sysinternals is a command line tool that does what you want.
如果您不想自己编写代码,Microsoft / Sysinternals的PsService是一个命令行工具,可以执行您想要的操作。
#5
You can use System.Management
APIs (WMI) to control services remotely. WMI is the generic API to do administrative tasks.
您可以使用System.Management API(WMI)远程控制服务。 WMI是执行管理任务的通用API。
For this problem, however, I suggest you to use the easier to use System.ServiceProcess.ServiceController
class.
但是,对于这个问题,我建议您使用更容易使用的System.ServiceProcess.ServiceController类。
#6
if you need to get the name of the Service:
如果您需要获取服务的名称:
run this from the command line:
从命令行运行:
sc query
You will see for example, that SQL Server's service name is 'MSSQL$SQLEXPRESS'.
例如,您将看到SQL Server的服务名称为“MSSQL $ SQLEXPRESS”。
So to stop the SQL Server service in C#:
所以要在C#中停止SQL Server服务:
ServiceController controller = new ServiceController();
controller.MachineName = "Machine1";
controller.ServiceName = "MSSQL$SQLEXPRESS";
if(controller.Status == ServiceControllerStatus.Running)
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
#7
galets code snippet above is a great start. However, keep in mind it assumes that the service has already started, or, more importantly, that
上面的galets代码片段是一个很好的开始。但是,请记住,它假设服务已经开始,或者更重要的是,它已经开始
sc.Status == System.ServiceProcess.ServiceControllerStatus.Running
Also, it may important to, at some point during code execution, call
此外,在代码执行期间的某些时候调用也很重要
sc.Refresh();
because the properties values (such as ServiceControllerStatus) may not reflect the actual properties of the service. For instance, you may call
因为属性值(例如ServiceControllerStatus)可能无法反映服务的实际属性。例如,你可以打电话
sc.Start();
and wait indefinitely when this command executes
并且在执行此命令时无限期地等待
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running)
Here is a version of this code that I coded with those considerations in mind.
以下是此代码的一个版本,我在编写时考虑了这些注意事项。
//Restart Content Service on DEV.
String svcName = "TheServiceName";
String machineName = "TheMachineName";
var sc = new System.ServiceProcess.ServiceController(svcName, machineName);
Console.WriteLine("Stopping Service '{0}' on machine '{1}", svcName, machineName);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
//sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
do
{
try
{
sc.Refresh();
if (sc.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
Console.WriteLine("Code has detected that servive start is pending, waiting 5 seconds to see if status changes..");
System.Threading.Thread.Sleep(5000);
}
else
{
Console.WriteLine("waiting 5 seconds and retrying start..");
System.Threading.Thread.Sleep(5000);
Console.WriteLine("Attempt Starting Service '{0}' on machine '{1}", svcName, machineName);
sc.Start();
}
}
catch(Exception ex)
{
//If it is already running, then abort do while
if (ex.InnerException.Message == "An instance of the service is already running")
{
Console.WriteLine(ex.InnerException.Message);
continue;
}
Console.WriteLine(ex.InnerException.ToString());
}
} while (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running);
#8
I Have done like below:
我做了如下:
Note:
- If you did't start your service if you are trying to stop it will throw exception.
- If you configure these things in your web.config ,configuration related exception will not come. No need to do anything in IIS.
如果您在尝试停止时未启动服务,则会抛出异常。
如果在web.config中配置这些内容,则不会出现与配置相关的异常。无需在IIS中执行任何操作。
In Web.Config
under <configuration>
在
<appSettings>
<add key="ServiceName" value="YourServiceName" />
<add key="MachineName" value="YourMachineName" />
</appSettings>
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true" userName="YourUserName" password="YourPassword"/>
</system.web>
In My Service Class:
在我的服务类中:
private void RestartService()
{
string serviceName = System.Configuration.ConfigurationSettings.AppSettings["ServiceName"];
string machineName = System.Configuration.ConfigurationSettings.AppSettings["MachineName"];
try
{
var service = new ServiceController(serviceName);
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
}
catch (Exception)
{
}
}
Hope this Helps.,
希望这可以帮助。,
#9
Here is a ServiceExtension that can Start and Stop Services on remote pc's.
这是一个可以在远程PC上启动和停止服务的ServiceExtension。
And it can set the Startup type of the service, even to "automatic (delayed)"
它可以设置服务的启动类型,甚至可以设置为“自动(延迟)”
modified version from this Answer to work on remote machines.
本答案中的修改版本可以在远程计算机上运行。
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.ServiceProcess;
namespace Helpers
{
public enum ServiceStartModeEx
{
Automatic = 2,
Manual = 3,
Disabled = 4,
DelayedAutomatic = 99
}
/// <summary>
/// Extensions to the ServiceController class.
/// </summary>
public static class ServiceControlerExtensions
{
/// <summary>
/// Set the start mode for the service.
/// </summary>
/// <param name="serviceController">The service controller.</param>
/// <param name="mode">The desired start mode.</param>
public static void SetStartMode(this ServiceController serviceController, ServiceStartModeEx mode)
{
IntPtr serviceManagerHandle = OpenServiceManagerHandle(serviceController);
IntPtr serviceHandle = OpenServiceHandle(serviceController, serviceManagerHandle);
try
{
if (mode == ServiceStartModeEx.DelayedAutomatic)
{
ChangeServiceStartType(serviceHandle, ServiceStartModeEx.Automatic);
ChangeDelayedAutoStart(serviceHandle, true);
}
else
{
// Delayed auto-start overrides other settings, so it must be set first.
ChangeDelayedAutoStart(serviceHandle, false);
ChangeServiceStartType(serviceHandle, mode);
}
}
finally
{
if (serviceHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceHandle);
}
if (serviceManagerHandle != IntPtr.Zero)
{
CloseServiceHandle(serviceManagerHandle);
}
}
}
private static IntPtr OpenServiceHandle(ServiceController serviceController, IntPtr serviceManagerHandle)
{
var serviceHandle = OpenService(
serviceManagerHandle,
serviceController.ServiceName,
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
if (serviceHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Error");
}
return serviceHandle;
}
private static IntPtr OpenServiceManagerHandle(ServiceController serviceController)
{
var machineName = string.IsNullOrWhiteSpace(serviceController.MachineName)
? null
: serviceController.MachineName;
IntPtr serviceManagerHandle = OpenSCManager(machineName, null, SC_MANAGER_ALL_ACCESS);
if (serviceManagerHandle == IntPtr.Zero)
{
throw new ExternalException("Open Service Manager Error");
}
return serviceManagerHandle;
}
private static void ChangeServiceStartType(IntPtr serviceHandle, ServiceStartModeEx mode)
{
bool result = ChangeServiceConfig(
serviceHandle,
SERVICE_NO_CHANGE,
(uint)mode,
SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
null,
null,
null);
if (result == false)
{
ThrowLastWin32Error("Could not change service start type");
}
}
private static void ChangeDelayedAutoStart(IntPtr hService, bool delayed)
{
// Create structure that contains DelayedAutoStart property.
SERVICE_DELAYED_AUTO_START_INFO info = new SERVICE_DELAYED_AUTO_START_INFO();
// Set the DelayedAutostart property in that structure.
info.fDelayedAutostart = delayed;
// Allocate necessary memory.
IntPtr hInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_DELAYED_AUTO_START_INFO)));
// Convert structure to pointer.
Marshal.StructureToPtr(info, hInfo, true);
// Change the configuration.
bool result = ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, hInfo);
// Release memory.
Marshal.FreeHGlobal(hInfo);
if (result == false)
{
ThrowLastWin32Error("Could not set service to delayed automatic");
}
}
private static void ThrowLastWin32Error(string messagePrefix)
{
int nError = Marshal.GetLastWin32Error();
var win32Exception = new Win32Exception(nError);
string message = string.Format("{0}: {1}", messagePrefix, win32Exception.Message);
throw new ExternalException(message);
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr OpenService(
IntPtr hSCManager,
string lpServiceName,
uint dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
SetLastError = true)]
private static extern IntPtr OpenSCManager(
string machineName,
string databaseName,
uint dwAccess);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern Boolean ChangeServiceConfig(
IntPtr hService,
UInt32 nServiceType,
UInt32 nStartType,
UInt32 nErrorControl,
String lpBinaryPathName,
String lpLoadOrderGroup,
IntPtr lpdwTagId,
[In] char[] lpDependencies,
String lpServiceStartName,
String lpPassword,
String lpDisplayName);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ChangeServiceConfig2(
IntPtr hService,
int dwInfoLevel,
IntPtr lpInfo);
[DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
private static extern int CloseServiceHandle(IntPtr hSCObject);
private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
private const uint SERVICE_QUERY_CONFIG = 0x00000001;
private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
private const int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SERVICE_DELAYED_AUTO_START_INFO
{
public bool fDelayedAutostart;
}
}
}
You can start a service like this
你可以开始这样的服务
using System.ServiceProcess;
serviceName = "the name of the service"
serviceName =“服务名称”
machineName = "the name of the remote/local host"
machineName =“远程/本地主机的名称”
var service = new ServiceController(serviceName, machineName);
try
{
service.SetStartMode(ServiceStartModeEx.DelayedAutomatic);
service.Start();
}
finally
{
service.Close();
}
You can stop a service like this
你可以停止这样的服务
var service = new ServiceController(serviceName, machineName);
try
{
if (service.CanStop)
{
service.SetStartMode(ServiceStartModeEx.Disabled);
service.Stop();
}
}
finally
{
service.Close();
}
To grant a user rights to start and stop a service on a remote pc you have to set some service rights, you can google what subinacl.exe is and where to download it.
要授予用户在远程PC上启动和停止服务的权限,您必须设置一些服务权限,您可以google subinacl.exe是什么以及在何处下载它。
C:\Program Files (x86)\Windows Resource Kits\Tools>subinacl.exe /service SERVICENAME /grant=MACHINENAME\USERNAME=F