位置: 文档库 > C#(.NET) > C#启动,停止Windows服务

C#启动,停止Windows服务

宋应星 上传于 2021-05-21 17:12

《C#启动、停止Windows服务:从基础到进阶的完整指南》

Windows服务作为操作系统后台运行的核心组件,承担着数据库、网络通信、定时任务等关键功能。通过C#编程控制服务的启动与停止,不仅能实现自动化运维,还能提升系统管理的灵活性。本文将系统讲解如何使用.NET框架中的ServiceController类实现服务的精准控制,涵盖基础操作、异常处理、异步编程及安全验证等核心场景。

一、Windows服务基础与ServiceController类

Windows服务(Windows Service)是运行在后台的独立进程,无需用户交互即可持续执行。其生命周期由服务控制管理器(SCM)管理,支持启动、暂停、继续、停止等操作。.NET Framework通过System.ServiceProcess命名空间下的ServiceController类提供对服务的编程控制能力。

ServiceController类核心属性与方法:

  • ServiceName:获取或设置服务名称(必须与注册表中的名称一致)
  • Status:获取当前服务状态(Stopped/Running/Paused等)
  • Start():启动服务
  • Stop():停止服务
  • Refresh():更新服务状态信息
  • WaitForStatus(ServiceControllerStatus, TimeSpan):等待服务达到指定状态

服务状态转换图:

Stopped → Starting → Running
Running → Stopping → Stopped
Running → Pausing → Paused → Continuing → Running

二、基础服务控制实现

1. 启动Windows服务

启动服务需遵循以下步骤:

  1. 创建ServiceController实例
  2. 检查服务是否存在
  3. 验证当前状态是否为Stopped
  4. 调用Start()方法
  5. 等待服务进入Running状态
using System.ServiceProcess;

public static bool StartService(string serviceName, int timeoutMilliseconds)
{
    using (var controller = new ServiceController(serviceName))
    {
        try
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

            if (controller.Status != ServiceControllerStatus.Running)
            {
                controller.Start();
                controller.WaitForStatus(ServiceControllerStatus.Running, timeout);
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"启动服务失败: {ex.Message}");
            return false;
        }
    }
}

2. 停止Windows服务

停止服务需处理依赖关系和服务停止超时问题:

public static bool StopService(string serviceName, int timeoutMilliseconds)
{
    using (var controller = new ServiceController(serviceName))
    {
        try
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

            if (controller.Status == ServiceControllerStatus.Running)
            {
                controller.Stop();
                controller.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"停止服务失败: {ex.Message}");
            return false;
        }
    }
}

3. 状态查询与验证

服务状态查询示例:

public static string GetServiceStatus(string serviceName)
{
    using (var controller = new ServiceController(serviceName))
    {
        controller.Refresh();
        return controller.Status.ToString();
    }
}

三、进阶功能实现

1. 异步服务控制

使用async/await模式实现非阻塞操作:

public static async Task StartServiceAsync(string serviceName, int timeoutMilliseconds)
{
    using (var controller = new ServiceController(serviceName))
    {
        try
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

            if (controller.Status != ServiceControllerStatus.Running)
            {
                controller.Start();
                await controller.WaitForStatusAsync(ServiceControllerStatus.Running, timeout);
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"异步启动失败: {ex.Message}");
            return false;
        }
    }
}

2. 批量服务操作

实现多服务顺序控制:

public static bool ControlMultipleServices(
    Dictionary services)
{
    foreach (var (serviceName, (start, timeout)) in services)
    {
        bool success = start 
            ? StartService(serviceName, timeout)
            : StopService(serviceName, timeout);
        
        if (!success) return false;
    }
    return true;
}

3. 服务依赖检查

检测服务依赖关系:

using System.Management; // 需添加System.Management引用

public static List GetServiceDependencies(string serviceName)
{
    var dependencies = new List();
    var searcher = new ManagementObjectSearcher(
        $"SELECT * FROM Win32_DependentService WHERE Antecedent = \"Win32_Service.Name='{serviceName}'\"");
    
    foreach (ManagementObject obj in searcher.Get())
    {
        dependencies.Add(obj["Dependent"].ToString().Split('=')[1].Trim('\''));
    }
    return dependencies;
}

四、异常处理与最佳实践

1. 常见异常处理

异常类型 原因 解决方案
InvalidOperationException 服务不存在或状态无效 检查ServiceName拼写,验证服务状态
Win32Exception 权限不足或服务拒绝操作 以管理员身份运行程序
TimeoutException 服务未在指定时间内响应 增加超时时间或检查服务日志

2. 安全验证机制

实现权限检查的封装方法:

public static bool HasAdministratorRights()
{
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

3. 日志记录系统

集成NLog的日志记录示例:

using NLog;

private static readonly Logger logger = LogManager.GetCurrentClassLogger();

public static void SafeStartService(string serviceName)
{
    try
    {
        if (StartService(serviceName, 5000))
            logger.Info($"服务 {serviceName} 启动成功");
        else
            logger.Warn($"服务 {serviceName} 启动未完成");
    }
    catch (Exception ex)
    {
        logger.Error(ex, $"启动服务 {serviceName} 时发生错误");
    }
}

五、完整示例:服务管理工具类

using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Threading.Tasks;

public class ServiceManager : IDisposable
{
    private readonly ServiceController _controller;
    private readonly int _defaultTimeout = 5000;

    public ServiceManager(string serviceName)
    {
        _controller = new ServiceController(serviceName);
    }

    public async Task StartAsync(int? timeout = null)
    {
        try
        {
            var effectiveTimeout = timeout ?? _defaultTimeout;
            
            if (_controller.Status != ServiceControllerStatus.Running)
            {
                _controller.Start();
                await _controller.WaitForStatusAsync(
                    ServiceControllerStatus.Running, 
                    TimeSpan.FromMilliseconds(effectiveTimeout));
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"启动错误: {ex.Message}");
            return false;
        }
    }

    public async Task StopAsync(int? timeout = null)
    {
        try
        {
            var effectiveTimeout = timeout ?? _defaultTimeout;
            
            if (_controller.Status == ServiceControllerStatus.Running)
            {
                _controller.Stop();
                await _controller.WaitForStatusAsync(
                    ServiceControllerStatus.Stopped, 
                    TimeSpan.FromMilliseconds(effectiveTimeout));
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"停止错误: {ex.Message}");
            return false;
        }
    }

    public void Dispose()
    {
        _controller?.Dispose();
    }
}

六、实际应用场景

1. 自动化部署脚本

// 部署后自动启动服务
var manager = new ServiceManager("MyAppService");
if (!await manager.StartAsync())
{
    Environment.Exit(1);
}

2. 健康检查系统

public static bool CheckServiceHealth(string serviceName)
{
    using (var controller = new ServiceController(serviceName))
    {
        controller.Refresh();
        return controller.Status == ServiceControllerStatus.Running 
            && controller.CanStop 
            && controller.CanPauseAndContinue;
    }
}

3. 跨平台兼容方案

通过条件编译实现Linux服务控制(需.NET Core):

#if NETCOREAPP
    // 使用System.Diagnostics.Process调用systemctl
#else
    // 使用ServiceController
#endif

关键词:C#、Windows服务、ServiceController、异步编程、服务控制、异常处理权限验证NLog日志、依赖检查

简介:本文详细介绍使用C#(.NET)控制Windows服务的完整方案,涵盖基础操作、异步实现、依赖检查、安全验证等核心功能,提供从简单控制到企业级管理的完整实现路径,包含代码示例和最佳实践建议。

《C#启动,停止Windows服务.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档