以用户友好的方式管理Windows服务的工具

主窗体程序:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.ServiceProcess;
using System.Windows.Forms;
using CCWin;



//添加服务描述
//自动更新服务状态
//创建-删除 一个服务
//显示服务属性
namespace WinServMgr
{
    public partial class MainForm : CCSkinMain
    {
        #region 私有字段

        private const string InitialFilterText = "过滤...";
        private readonly SrvController mSrvController;
        private readonly BindingList<ServiceEntry> servicesList;
        private bool mFilterEmpty = true;
        private BindingSource servicesListBindingSource;

        #endregion

        #region 构造函数

        public MainForm()
        {
            InitializeComponent();
            mSrvController = new SrvController(this);
            servicesList = new BindingList<ServiceEntry>();
            servicesListBindingSource = new BindingSource(servicesList, null);
            dgvServicesList.DataSource = servicesListBindingSource;
            dgvServicesList.RowHeadersWidth = 12;
            dgvServicesList.Columns["ServiceState"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dgvServicesList.Columns["ServiceName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }

        #endregion

        #region 公有成员

        /// <summary>
        ///     获取在网格视图中选择的服务列表。
        ///     该服务被视为选择,如果:
        ///     1.选择包含其名称的单元格
        ///     2.选择服务行
        /// </summary>
        /// <returns></returns>
        public List<string> GetSelectedServices()
        {
            var selectedServices = new List<string>();

            try
            {
                DataGridViewSelectedRowCollection selectedRows = dgvServicesList.SelectedRows;
                if (selectedRows.Count > 0)
                {
                    foreach (DataGridViewRow row in selectedRows)
                    {
                        selectedServices.Add(GetServiceNameForRow(row));
                    }
                }

                DataGridViewSelectedCellCollection selectedCells = dgvServicesList.SelectedCells;
                if (selectedCells.Count > 0)
                {
                    foreach (DataGridViewCell cell in selectedCells)
                    {
                        if (cell.ColumnIndex == dgvServicesList.Columns["ServiceName"].Index)
                        {
                            selectedServices.Add(cell.Value as string);
                        }
                    }
                }
                return selectedServices;
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取选定服务时遇到异常:\n" + ex.Message);
            }

            return selectedServices;
        }

        /// <summary>
        ///     显示带有指定错误消息的消息框
        /// </summary>
        /// <param name="message">消息显示</param>
        public static void ShowError(string message)
        {
            MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion

        #region 私有成员

        private bool RefreshGrid()
        {
            // 1.如果不使用过滤器,我们会显示所有服务,否则以文本开头(case独立)
            // 2.如果选中“显示停止服务”复选框,我们也会显示它们
            List<ServiceEntry> filteredEntries = mSrvController.ServiceEntries.Where(s =>
                (mFilterEmpty || s.ServiceName.StartsWith(txtFilter.Text, StringComparison.CurrentCultureIgnoreCase)) &&
                (tbxShowStopped.Checked || s.ServiceState != ServiceControllerStatus.Stopped))
                .ToList();

            List<ServiceEntry> entriesToRemove = servicesList.Except(filteredEntries).ToList();
            foreach (ServiceEntry entry in entriesToRemove)
            {
                servicesList.Remove(entry);
            }

            List<ServiceEntry> newEntries = filteredEntries.Except(servicesList).ToList();
            foreach (ServiceEntry entry in newEntries)
            {
                //将一个条目插入到其位置,以便绑定列表按字母顺序排列
                if (servicesList.Count == 0)
                {
                    servicesList.Add(entry);
                }
                else
                {
                    ServiceEntry elementToInsertBefore =
                        servicesList.FirstOrDefault(e => e.ServiceName.CompareTo(entry.ServiceName) > 0);
                    if (elementToInsertBefore != null)
                    {
                        servicesList.Insert(servicesList.IndexOf(elementToInsertBefore), entry);
                    }
                    else
                    {
                        servicesList.Add(entry);
                    }
                }
            }

            UpdateStatusColors(newEntries);

            List<ServiceEntry> changedEntries = filteredEntries.Where(fe => fe.StateChanged).ToList();
            UpdateStatusColors(changedEntries);
            foreach (ServiceEntry entry in mSrvController.ServiceEntries)
            {
                if (changedEntries.Contains(entry))
                {
                    entry.StateChanged = false;
                }
            }

            return entriesToRemove.Any() || newEntries.Any() || changedEntries.Any(); // true if something has changed
        }

        private void UpdateStatusColors(IEnumerable<ServiceEntry> changedEntries)
        {
            foreach (ServiceEntry entry in changedEntries)
            {
                DataGridViewRow row = dgvServicesList.Rows.Cast<DataGridViewRow>().First(r =>
                    r.Cells["ServiceName"].Value.ToString() == entry.ServiceName);
                Color cellColor;
                switch (entry.ServiceState)
                {
                    case ServiceControllerStatus.Running:
                        cellColor = Color.Green;
                        break;
                    case ServiceControllerStatus.Stopped:
                        cellColor = Color.Red;
                        break;
                    default:
                        cellColor = Color.Gray;
                        break;
                }

                row.HeaderCell.Style.BackColor = cellColor;
                row.HeaderCell.Style.SelectionBackColor = cellColor;
            }
        }

        private void UpdateFormTitle()
        {
            Text = string.Format("Win服务管理[{0}活动服务]",
                mSrvController.ServiceEntries.Where(s => s.ServiceState != ServiceControllerStatus.Stopped).Count());
        }

        private void btnStopService_Click(object sender, EventArgs e)
        {
            mSrvController.PerformForSelected(name =>
            {
                var sc = new ServiceController(name);
                sc.Stop();
            }, "controlled stop");
        }

        private void btnStartService_Click(object sender, EventArgs e)
        {
            mSrvController.PerformForSelected(name =>
            {
                var sc = new ServiceController(name);
                sc.Start();
            }, "controlled start");
        }

        private void btnRestartService_Click(object sender, EventArgs e)
        {
            mSrvController.PerformForSelected(name =>
            {
                var sc = new ServiceController(name);
                sc.Stop();
                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(60));
                sc.Start();
            }, "controlled restart");
        }

        private string GetServiceNameForRow(DataGridViewRow row)
        {
            return row.Cells["ServiceName"].Value as string;
        }

        private void SMATestTool_Load(object sender, EventArgs e)
        {
            mSrvController.UpdateServiceEntries();
            if (RefreshGrid())
            {
                UpdateFormTitle();
            }

            tmrRefreshGrid.Enabled = true;
        }

        private void txtFilter_TextChanged(object sender, EventArgs e)
        {
            if (txtFilter.Text == InitialFilterText)
            {
                return;
            }
            if (txtFilter.Text == string.Empty)
            {
                mFilterEmpty = true;
            }
            else
            {
                mFilterEmpty = false;
            }
            RefreshGrid();
        }

        private void txtFilter_Enter(object sender, EventArgs e)
        {
            if (mFilterEmpty)
            {
                txtFilter.Text = "";
                txtFilter.ForeColor = Color.Black;
            }
        }

        private void txtFilter_Leave(object sender, EventArgs e)
        {
            if (mFilterEmpty)
            {
                txtFilter.Text = InitialFilterText;
                txtFilter.ForeColor = Color.Gray;
            }
        }

        private void tbxShowStopped_CheckedChanged(object sender, EventArgs e)
        {
            RefreshGrid();
        }

        private void dgvServicesList_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                // -1 表示  标题行 / 列
                if (e.RowIndex != -1 && e.ColumnIndex != -1)
                {
                    DataGridViewCell clickedCell = (sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex];
                    dgvServicesList.CurrentCell = clickedCell;

                    string serviceName = GetServiceNameForRow(dgvServicesList.Rows[e.RowIndex]);
                    ServiceControllerStatus state =
                        mSrvController.ServiceEntries.First(s => s.ServiceName == serviceName).ServiceState;

                    var cm = new ContextMenu();
                    var mi = new MenuItem("服务停止");
                    mi.Enabled = state != ServiceControllerStatus.Stopped;
                    mi.Click += btnStopService_Click;
                    cm.MenuItems.Add(mi);

                    mi = new MenuItem("服务启动");
                    mi.Enabled = state != ServiceControllerStatus.Running;
                    mi.Click += btnStartService_Click;
                    cm.MenuItems.Add(mi);

                    mi = new MenuItem("服务重启");
                    mi.Enabled = state != ServiceControllerStatus.Stopped;
                    mi.Click += btnRestartService_Click;
                    cm.MenuItems.Add(mi);

                    Point relativeMousePosition = dgvServicesList.PointToClient(Cursor.Position);
                    cm.Show(dgvServicesList, relativeMousePosition);
                }
            }
        }

        private void tmrRefreshGrid_Tick(object sender, EventArgs e)
        {
            mSrvController.UpdateServiceEntries();
            if (RefreshGrid())
            {
                UpdateFormTitle();
            }
        }

        #endregion
    }
}

ServiceEntry.cs:

using System.ComponentModel;
using System.ServiceProcess;

namespace WinServMgr
{
    public class ServiceEntry
    {
        public bool StateChanged;

        public ServiceEntry(string name, ServiceControllerStatus state)
        {
            ServiceName = name;
            ServiceState = state;
            StateChanged = true;
        }

        [DisplayName("服务名称")]
        public string ServiceName { get; set; }

        [DisplayName("服务状态")]
        public ServiceControllerStatus ServiceState { get; set; }

        public override bool Equals(object obj)
        {
            return ServiceName == (obj as ServiceEntry).ServiceName;
        }

        public override int GetHashCode()
        {
            return ServiceName.GetHashCode();
        }
    }
}

SrvController.cs:

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

namespace WinServMgr
{
    public class SrvController
    {
        private readonly MainForm mMainForm;
        private readonly object mSrvControllerLock = new object();

        public SrvController(MainForm mainForm)
        {
            ServiceEntries = new List<ServiceEntry>();
            mMainForm = mainForm;
        }

        public List<ServiceEntry> ServiceEntries { get; set; }

        /// <summary>
        ///    从系统获取服务的当前状态
        /// </summary>
        public void UpdateServiceEntries()
        {
            lock (mSrvControllerLock)
            {
                ServiceEntries.ForEach(se => se.StateChanged = false);
                List<ServiceEntry> newServicesEntries =
                    ServiceController.GetServices().Select(sc => new ServiceEntry(sc.ServiceName, sc.Status)).ToList();

                foreach (ServiceEntry se in ServiceEntries)
                {
                    int index = newServicesEntries.IndexOf(se);
                    if (index >= 0 && newServicesEntries[index].ServiceState != se.ServiceState)
                    {
                        se.ServiceState = newServicesEntries[index].ServiceState;
                        se.StateChanged = true;
                    }
                }

                ServiceEntries.AddRange(newServicesEntries.Except(ServiceEntries));
                ServiceEntries.RemoveAll(se => !newServicesEntries.Contains(se));
            }
        }

        /// <summary>
        ///  对选定的服务执行指定的操作
        /// </summary>
        /// <param name="action">需要使用服务完成哪个名称作为输入参数的操作</param>
        /// <param name="actionName">用户友好的操作名称(对于错误信息)</param>
        public void PerformForSelected(Action<string> action, string actionName)
        {
            var task = new Task(() =>
            {
                List<string> serviceNames = mMainForm.GetSelectedServices();
                serviceNames.AsParallel().ForAll(name =>
                {
                    try
                    {
                        action(name);
                    }
                    catch (Exception ex)
                    {
                        MainForm.ShowError(string.Format("执行时遇到异常 {0} of {1}:\n{2}",
                            actionName, name, ex.Message));
                    }
                });
            });
            task.Start();
        }
    }
}

运行结果如图:

这里写图片描述


这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值