主窗体程序:
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 公有成员
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;
}
public static void ShowError(string message)
{
MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
#endregion
#region 私有成员
private bool RefreshGrid()
{
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();
}
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)
{
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; }
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));
}
}
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();
}
}
}
运行结果如图:
![这里写图片描述](https://img-blog.csdn.net/20170510153428472)
![这里写图片描述](https://img-blog.csdn.net/20170510153454939)