c# – 以编程方式启用Windows服务
发布时间:2020-12-16 00:24:38 所属栏目:百科 来源:网络整理
导读:我试图通过修改注册表中的值以编程方式启用 Windows服务,如下所示.价值确实在变化.但是,之后我无法启动该服务,因为Windows仍然将其视为已禁用. public void EnabledTheService(string serviceName){ try { RegistryKey key = Registry.LocalMachine .OpenSub
我试图通过修改注册表中的值以编程方式启用
Windows服务,如下所示.价值确实在变化.但是,之后我无法启动该服务,因为Windows仍然将其视为已禁用.
public void EnabledTheService(string serviceName) { try { RegistryKey key = Registry.LocalMachine .OpenSubKey(@"SYSTEMCurrentControlSetServices" + serviceName,true); key.SetValue("Start",2); } catch (Exception ex) { Console.Write(ex.Message); } } public void StartService(string serviceName) { ServiceController service = new ServiceController(serviceName); try { service.Start(); service.WaitForStatus(ServiceControllerStatus.Running,new TimeSpan(0,20)); } catch (Exception ex) { Console.Write(ex.Message); } } 解决方法
有几种方法可以更改Windows服务的启动类型(请参阅
this question).如果我没记错,WMI方法在我测试时工作但不完全可靠,所以我使用了Windows API函数
ChangeServiceConfig.我从未尝试过注册表方法.我认为这将是三个选项中最不稳定的.
请注意,如果您想要“自动(延迟启动)”模式,则需要拨打ChangeServiceConfig2. public void ChangeServiceStartType(string serviceName,ServiceStartupType startType) { //Obtain a handle to the service control manager database IntPtr scmHandle = OpenSCManager(null,null,SC_MANAGER_CONNECT); if (scmHandle == IntPtr.Zero) { throw new Exception("Failed to obtain a handle to the service control manager database."); } //Obtain a handle to the specified windows service IntPtr serviceHandle = OpenService(scmHandle,serviceName,SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); if (serviceHandle == IntPtr.Zero) { throw new Exception($"Failed to obtain a handle to service '{serviceName}'."); } //Change the start mode bool changeServiceSuccess = ChangeServiceConfig(serviceHandle,SERVICE_NO_CHANGE,(uint)startType,IntPtr.Zero,null); if (!changeServiceSuccess) { string msg = $"Failed to update service configuration for service '{serviceName}'. ChangeServiceConfig returned error {Marshal.GetLastWin32Error()}."; throw new Exception(msg); } //Clean up if (scmHandle != IntPtr.Zero) CloseServiceHandle(scmHandle); if (serviceHandle != IntPtr.Zero) CloseServiceHandle(serviceHandle); } [DllImport("advapi32.dll",CharSet = CharSet.Auto,SetLastError = true)] private static extern IntPtr OpenSCManager(string machineName,string databaseName,uint dwAccess); [DllImport("advapi32.dll",SetLastError = true)] private static extern IntPtr OpenService(IntPtr hSCManager,string lpServiceName,uint dwDesiredAccess); [DllImport("advapi32.dll",SetLastError = true)] private static extern bool ChangeServiceConfig( IntPtr hService,uint nServiceType,uint nStartType,uint nErrorControl,string lpBinaryPathName,string lpLoadOrderGroup,IntPtr lpdwTagId,[In] char[] lpDependencies,string lpServiceStartName,string lpPassword,string lpDisplayName); [DllImport("advapi32.dll",EntryPoint = "CloseServiceHandle")] private static extern int CloseServiceHandle(IntPtr hSCObject); private const uint SC_MANAGER_CONNECT = 0x0001; private const uint SERVICE_QUERY_CONFIG = 0x00000001; private const uint SERVICE_CHANGE_CONFIG = 0x00000002; private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF; public enum ServiceStartupType : uint { /// <summary> /// A device driver started by the system loader. This value is valid only for driver services. /// </summary> BootStart = 0,/// <summary> /// A device driver started by the IoInitSystem function. This value is valid only for driver services. /// </summary> SystemStart = 1,/// <summary> /// A service started automatically by the service control manager during system startup. /// </summary> Automatic = 2,/// <summary> /// A service started by the service control manager when a process calls the StartService function. /// </summary> Manual = 3,/// <summary> /// A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED. /// </summary> Disabled = 4 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |