加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读