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

来源:互联网 发布:深入分析linux内核源码 编辑:程序博客网 时间:2024/05/17 13:43

主窗体程序:

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 0
原创粉丝点击