Windows系统实现服务安装管理
在做工程实施过程中我们经常遇到安装与管理系统服务的任务,尤其是现在各种无人值守的应用,大部分都是通过服务来实现。很多控制台应用,放在服务器上执行,其它人可能不小心关闭了,那么这时候相应的值守的程序就退出了,严重的可能会影响业务数据,造成数据丢失等严重问题。 为了解决这一问题,我开发了服务安装配置管理器 。该管理器具备服务的安装管理、服务的基本配置,开机自动启动,最小化托盘运行…。直接上图:
1.管理器主界面
2.创建服务界面
3.关于及版权
4.服务配置界面
可针对不同的服务进行相关的配置设置,无需去改动配置文件,就可实现配置文件的修改。
5.主界面介绍
主要实现代码
1.注册表操作类
/// <summary>
/// 注册表辅助类
/// </summary>
public class RegisterHelper
{
/// <summary>
/// 默认注册表基项
/// </summary>
private string baseKey = "Software";
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
/// <param name="baseKey">基项的名称</param>
public RegisterHelper()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="baseKey">基项的名称</param>
public RegisterHelper(string baseKey)
{
this.baseKey = baseKey;
}
#endregion
#region 公共方法
/// <summary>
/// 写入注册表,如果指定项已经存在,则修改指定项的值
/// </summary>
/// <param name="keytype">注册表基项枚举</param>
/// <param name="key">注册表项,不包括基项</param>
/// <param name="name">值名称</param>
/// <param name="values">值</param>
public void SetValue(KeyType keytype, string key, string name, string values)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey, true);
RegistryKey rkt = software.CreateSubKey(key);
if (rkt != null)
{
rkt.SetValue(name, values);
}
}
/// <summary>
/// 读取注册表
/// </summary>
/// <param name="keytype">注册表基项枚举</param>
/// <param name="key">注册表项,不包括基项</param>
/// <param name="name">值名称</param>
/// <returns>返回字符串</returns>
public string GetValue(KeyType keytype, string key, string name)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey, true);
RegistryKey rkt = software.OpenSubKey(key);
if (rkt != null)
{
return rkt.GetValue(name).ToString();
}
else
{
return string.Empty;
}
}
/// <summary>
/// 删除注册表中的值
/// </summary>
/// <param name="keytype">注册表基项枚举</param>
/// <param name="key">注册表项名称,不包括基项</param>
/// <param name="name">值名称</param>
public void DeleteValue(KeyType keytype, string key, string name)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey, true);
RegistryKey rkt = software.OpenSubKey(key, true);
if (rkt != null)
{
object value = rkt.GetValue(name);
if (value != null)
{
rkt.DeleteValue(name, true);
}
}
}
/// <summary>
/// 删除注册表中的指定项
/// </summary>
/// <param name="keytype">注册表基项枚举</param>
/// <param name="key">注册表中的项,不包括基项</param>
/// <returns>返回布尔值,指定操作是否成功</returns>
public void DeleteSubKey(KeyType keytype, string key)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey, true);
if (software != null)
{
software.DeleteSubKeyTree(key);
}
}
/// <summary>
/// 判断指定项是否存在
/// </summary>
/// <param name="keytype">基项枚举</param>
/// <param name="key">指定项字符串</param>
/// <returns>返回布尔值,说明指定项是否存在</returns>
public bool IsExist(KeyType keytype, string key)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey);
RegistryKey rkt = software.OpenSubKey(key);
if (rkt != null)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 检索指定项关联的所有值
/// </summary>
/// <param name="keytype">基项枚举</param>
/// <param name="key">指定项字符串</param>
/// <returns>返回指定项关联的所有值的字符串数组</returns>
public string[] GetValues(KeyType keytype, string key)
{
RegistryKey rk = (RegistryKey)GetRegistryKey(keytype);
RegistryKey software = rk.OpenSubKey(baseKey, true);
RegistryKey rkt = software.OpenSubKey(key);
string[] names = rkt.GetValueNames();
if (names.Length == 0)
{
return names;
}
else
{
string[] values = new string[names.Length];
int i = 0;
foreach (string name in names)
{
values[i] = rkt.GetValue(name).ToString();
i++;
}
return values;
}
}
/// <summary>
/// 将对象所有属性写入指定注册表中
/// </summary>
/// <param name="keytype">注册表基项枚举</param>
/// <param name="key">注册表项,不包括基项</param>
/// <param name="obj">传入的对象</param>
public void SetObjectValue(KeyType keyType, string key, Object obj)
{
if (obj != null)
{
Type t = obj.GetType();
string name;
object value;
foreach (var p in t.GetProperties())
{
if (p != null)
{
name = p.Name;
value = p.GetValue(obj, null);
this.SetValue(keyType, key, name, value.ToString());
}
}
}
}
#endregion
#region 私有方法
/// <summary>
/// 返回RegistryKey对象
/// </summary>
/// <param name="keyType">注册表基项枚举</param>
/// <returns></returns>
private object GetRegistryKey(KeyType keyType)
{
RegistryKey rk = null;
switch (keyType)
{
case KeyType.HKEY_CLASS_ROOT:
rk = Registry.ClassesRoot;
break;
case KeyType.HKEY_CURRENT_USER:
rk = Registry.CurrentUser;
break;
case KeyType.HKEY_LOCAL_MACHINE:
rk = Registry.LocalMachine;
break;
case KeyType.HKEY_USERS:
rk = Registry.Users;
break;
case KeyType.HKEY_CURRENT_CONFIG:
rk = Registry.CurrentConfig;
break;
}
return rk;
}
#endregion
#region 枚举
/// <summary>
/// 注册表基项枚举
/// </summary>
public enum KeyType : int
{
/// <summary>
/// 注册表基项 HKEY_CLASSES_ROOT
/// </summary>
HKEY_CLASS_ROOT,
/// <summary>
/// 注册表基项 HKEY_CURRENT_USER
/// </summary>
HKEY_CURRENT_USER,
/// <summary>
/// 注册表基项 HKEY_LOCAL_MACHINE
/// </summary>
HKEY_LOCAL_MACHINE,
/// <summary>
/// 注册表基项 HKEY_USERS
/// </summary>
HKEY_USERS,
/// <summary>
/// 注册表基项 HKEY_CURRENT_CONFIG
/// </summary>
HKEY_CURRENT_CONFIG
}
#endregion
}
2.系统帮助类
/// <summary>
/// 系统帮助类
/// </summary>
public class SystemHelper
{
/// <summary>
/// 检查服务启动状态
/// </summary>
/// <param name="serviceName">服务名称</param>
/// <returns>启动为true</returns>
public static bool CheckServiceStatus(string serviceName)
{
ServiceController[] service = ServiceController.GetServices();
bool isStart = false;
for (int i = 0; i < service.Length; i++)
{
if (service[i].ServiceName.Equals(
serviceName,
StringComparison.CurrentCultureIgnoreCase))
{
if (service[i].Status == ServiceControllerStatus.Running)
{
isStart = true;
break;
}
}
}
return isStart;
}
/// <summary>
///
/// </summary>
/// <param name="appName"></param>
/// <returns></returns>
public static bool CheckAppStatus(string appName)
{
bool isStart = false;
foreach (Process p in Process.GetProcesses())
{
if (p.ProcessName.IndexOf(
appName,
StringComparison.CurrentCultureIgnoreCase) > -1)
{
isStart = true;
break;
}
}
return isStart;
}
}
3.服务帮助类
#region 异常定义
/// <summary>
/// 服务不存在异常
/// </summary>
public class ServiceNotExistException : ApplicationException
{
public ServiceNotExistException() : base("服务不存在!") { }
public ServiceNotExistException(string message) : base(message) { }
}
#endregion
#region 枚举定义
/// <summary>
/// 服务启动类型
/// </summary>
public enum ServiceStartType
{
Boot,
System,
Auto,
Manual,
Disabled
}
/// <summary>
/// 服务运行帐户
/// </summary>
public enum ServiceAccount
{
LocalSystem,
LocalService,
NetworkService,
}
#endregion
/// <summary>
/// Windows 服务辅助类
/// </summary>
public class ServiceHelper
{
#region 公开方法
/// <summary>
/// 安装服务
/// </summary>
/// <param name="serviceName">服务名</param>
/// <param name="displayName">友好名称</param>
/// <param name="binaryFilePath">映像文件路径,可带参数</param>
/// <param name="description">服务描述</param>
/// <param name="startType">启动类型</param>
/// <param name="account">启动账户</param>
/// <param name="dependencies">依赖服务</param>
public static void Install(string serviceName, string displayName, string binaryFilePath, string description, ServiceStartType startType, ServiceAccount account = ServiceAccount.LocalSystem, string[] dependencies = null)
{
IntPtr scm = OpenSCManager();
IntPtr service = IntPtr.Zero;
try
{
service = Win32Class.CreateService(scm, serviceName, displayName, Win32Class.SERVICE_ALL_ACCESS, Win32Class.SERVICE_WIN32_OWN_PROCESS, startType, Win32Class.SERVICE_ERROR_NORMAL, binaryFilePath, null, IntPtr.Zero, ProcessDependencies(dependencies), GetServiceAccountName(account), null);
if (service == IntPtr.Zero)
{
if (Marshal.GetLastWin32Error() == 0x431)//ERROR_SERVICE_EXISTS
{ throw new ApplicationException("服务已存在!"); }
throw new ApplicationException("服务安装失败!");
}
//设置服务描述
Win32Class.SERVICE_DESCRIPTION sd = new Win32Class.SERVICE_DESCRIPTION();
try
{
sd.description = Marshal.StringToHGlobalUni(description);
Win32Class.ChangeServiceConfig2(service, 1, ref sd);
}
finally
{
Marshal.FreeHGlobal(sd.description); //释放
}
}
finally
{
if (service != IntPtr.Zero)
{
Win32Class.CloseServiceHandle(service);
}
Win32Class.CloseServiceHandle(scm);
}
}
/// <summary>
/// 卸载服务
/// </summary>
/// <param name="serviceName">服务名</param>
public static void Uninstall(string serviceName)
{
IntPtr scmHandle = IntPtr.Zero;
IntPtr service = IntPtr.Zero;
try
{
service = OpenService(serviceName, out scmHandle);
StopService(service); //停止服务。里面会递归停止从属服务
if (!Win32Class.DeleteService(service) && Marshal.GetLastWin32Error() != 0x430) //忽略已标记为删除的服务。ERROR_SERVICE_MARKED_FOR_DELETE
{
throw new ApplicationException("删除服务失败!");
}
}
catch (ServiceNotExistException) { } //忽略服务不存在的情况
finally
{
if (service != IntPtr.Zero)
{
Win32Class.CloseServiceHandle(service);
Win32Class.CloseServiceHandle(scmHandle);//放if里面是因为如果服务打开失败,在OpenService里就已释放SCM
}
}
}
#endregion
#region 辅助方法
/// <summary>
/// 转换帐户枚举为有效参数
/// </summary>
public static string GetServiceAccountName(ServiceAccount account)
{
if (account == ServiceAccount.LocalService)
{
return @"NT AUTHORITYLocalService";
}
if (account == ServiceAccount.NetworkService)
{
return @"NT AUTHORITYNetworkService";
}
return null;
}
/// <summary>
/// 处理依赖服务参数
/// </summary>
public static string ProcessDependencies(string[] dependencies)
{
if (dependencies == null || dependencies.Length == 0)
{
return null;
}
StringBuilder sb = new StringBuilder();
foreach (string s in dependencies)
{
sb.Append(s).Append("");
}
sb.Append("");
return sb.ToString();
}
#endregion
#region API 封装方法
/// <summary>
/// 打开服务管理器
/// </summary>
public static IntPtr OpenSCManager()
{
IntPtr scm = Win32Class.OpenSCManager(null, null, Win32Class.SC_MANAGER_ALL_ACCESS);
if (scm == IntPtr.Zero)
{
throw new ApplicationException("打开服务管理器失败!");
}
return scm;
}
/// <summary>
/// 打开服务
/// </summary>
/// <param name="serviceName">服务名称</param>
/// <param name="scmHandle">服务管理器句柄。供调用者释放</param>
public static IntPtr OpenService(string serviceName, out IntPtr scmHandle)
{
scmHandle = OpenSCManager();
IntPtr service = Win32Class.OpenService(scmHandle, serviceName, Win32Class.SERVICE_ALL_ACCESS);
if (service == IntPtr.Zero)
{
int errCode = Marshal.GetLastWin32Error();
Win32Class.CloseServiceHandle(scmHandle); //关闭SCM
if (errCode == 0x424) //ERROR_SERVICE_DOES_NOT_EXIST
{
throw new ServiceNotExistException();
}
throw new Win32Exception();
}
return service;
}
public static bool ExistService(string serviceName)
{
IntPtr scmHandle = IntPtr.Zero;
IntPtr handle = IntPtr.Zero;
try
{
handle = OpenService(serviceName, out scmHandle);
if (handle == IntPtr.Zero)
{
int errCode = Marshal.GetLastWin32Error();
if (errCode == 0x424)
{ return false; }
}
}
catch (ServiceNotExistException e) { return false; }
finally
{
Win32Class.CloseServiceHandle(scmHandle); //关闭SCM
Win32Class.CloseServiceHandle(handle); //关闭服务
}
return true;
}
public static bool StartService(string serviceName, TimeSpan timeSpan)
{
if (!ExistService(serviceName)) return false;
System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(serviceName);
if (sc.Status != System.ServiceProcess.ServiceControllerStatus.Running && sc.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
{
sc.Start();
}
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, timeSpan);
return sc.Status == System.ServiceProcess.ServiceControllerStatus.Running;
}
public static bool StopService(string serviceName, TimeSpan timeSpan)
{
if (!ExistService(serviceName)) return false;
System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(serviceName);
if (sc.Status != System.ServiceProcess.ServiceControllerStatus.Stopped && sc.Status != System.ServiceProcess.ServiceControllerStatus.StopPending)
{
sc.Stop();
}
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, timeSpan);
var isok = sc.Status == System.ServiceProcess.ServiceControllerStatus.Stopped;
sc.Close();
sc.Dispose();
return isok;
}
/// <summary>
/// 停止服务
/// </summary>
public static void StopService(IntPtr service)
{
ServiceState currState = GetServiceStatus(service);
if (currState == ServiceState.Stopped)
{
return;
}
if (currState != ServiceState.StopPending)
{
//递归停止从属服务
string[] childSvs = EnumDependentServices(service, EnumServiceState.Active);
if (childSvs.Length != 0)
{
IntPtr scm = OpenSCManager();
try
{
foreach (string childSv in childSvs)
{
StopService(Win32Class.OpenService(scm, childSv, Win32Class.SERVICE_STOP));
}
}
finally
{
Win32Class.CloseServiceHandle(scm);
}
}
Win32Class.SERVICE_STATUS status = new Win32Class.SERVICE_STATUS();
Win32Class.ControlService(service, Win32Class.SERVICE_CONTROL_STOP, ref status); //发送停止指令
}
if (!WaitForStatus(service, ServiceState.Stopped, new TimeSpan(0, 0, 30)))
{
throw new ApplicationException("停止服务失败!");
}
}
/// <summary>
/// 遍历从属服务
/// </summary>
/// <param name="serviceHandle"></param>
/// <param name="state">选择性遍历(活动、非活动、全部)</param>
public static string[] EnumDependentServices(IntPtr serviceHandle, EnumServiceState state)
{
int bytesNeeded = 0; //存放从属服务的空间大小,由API返回
int numEnumerated = 0; //从属服务数,由API返回
//先尝试以空结构获取,如获取成功说明从属服务为空,否则拿到上述俩值
if (Win32Class.EnumDependentServices(serviceHandle, state, IntPtr.Zero, 0, ref bytesNeeded, ref numEnumerated))
{
return new string[0];
}
if (Marshal.GetLastWin32Error() != 0xEA) //仅当错误值不是大小不够(ERROR_MORE_DATA)时才抛异常
{
throw new Win32Exception();
}
//在非托管区域创建指针
IntPtr structsStart = Marshal.AllocHGlobal(new IntPtr(bytesNeeded));
try
{
//往上述指针处塞存放从属服务的结构组,每个从属服务是一个结构
if (!Win32Class.EnumDependentServices(serviceHandle, state, structsStart, bytesNeeded, ref bytesNeeded, ref numEnumerated))
{
throw new Win32Exception();
}
string[] dependentServices = new string[numEnumerated];
int sizeOfStruct = Marshal.SizeOf(typeof(Win32Class.ENUM_SERVICE_STATUS)); //每个结构的大小
long structsStartAsInt64 = structsStart.ToInt64();
for (int i = 0; i < numEnumerated; i++)
{
Win32Class.ENUM_SERVICE_STATUS structure = new Win32Class.ENUM_SERVICE_STATUS();
IntPtr ptr = new IntPtr(structsStartAsInt64 + i * sizeOfStruct); //根据起始指针、结构次序和结构大小推算各结构起始指针
Marshal.PtrToStructure(ptr, structure); //根据指针拿到结构
dependentServices[i] = structure.serviceName; //从结构中拿到服务名
}
return dependentServices;
}
finally
{
Marshal.FreeHGlobal(structsStart);
}
}
/// <summary>
/// 获取服务状态
/// </summary>
public static ServiceState GetServiceStatus(IntPtr service)
{
Win32Class.SERVICE_STATUS status = new Win32Class.SERVICE_STATUS();
if (!Win32Class.QueryServiceStatus(service, ref status))
{
throw new ApplicationException("获取服务状态出错!");
}
return status.currentState;
}
/// <summary>
/// 等候服务至目标状态
/// </summary>
public static bool WaitForStatus(IntPtr serviceHandle, ServiceState desiredStatus, TimeSpan timeout)
{
DateTime startTime = DateTime.Now;
while (GetServiceStatus(serviceHandle) != desiredStatus)
{
if (DateTime.Now - startTime > timeout) { return false; }
Thread.Sleep(200);
}
return true;
}
#endregion
#region 嵌套类
/// <summary>
/// Win32 API相关
/// </summary>
private static class Win32Class
{
#region 常量定义
/// <summary>
/// 打开服务管理器时请求的权限:全部
/// </summary>
public const int SC_MANAGER_ALL_ACCESS = 0xF003F;
/// <summary>
/// 服务类型:自有进程类服务
/// </summary>
public const int SERVICE_WIN32_OWN_PROCESS = 0x10;
/// <summary>
/// 打开服务时请求的权限:全部
/// </summary>
public const int SERVICE_ALL_ACCESS = 0xF01FF;
/// <summary>
/// 打开服务时请求的权限:停止
/// </summary>
public const int SERVICE_STOP = 0x20;
/// <summary>
/// 服务操作标记:停止
/// </summary>
public const int SERVICE_CONTROL_STOP = 0x1;
/// <summary>
/// 服务出错行为标记
/// </summary>
public const int SERVICE_ERROR_NORMAL = 0x1;
#endregion
#region API所需类和结构定义
/// <summary>
/// 服务状态结构体
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SERVICE_STATUS
{
public int serviceType;
public ServiceState currentState;
public int controlsAccepted;
public int win32ExitCode;
public int serviceSpecificExitCode;
public int checkPoint;
public int waitHint;
}
/// <summary>
/// 服务描述结构体
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SERVICE_DESCRIPTION
{
public IntPtr description;
}
/// <summary>
/// 服务状态结构体。遍历API会用到
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class ENUM_SERVICE_STATUS
{
public string serviceName;
public string displayName;
public int serviceType;
public int currentState;
public int controlsAccepted;
public int win32ExitCode;
public int serviceSpecificExitCode;
public int checkPoint;
public int waitHint;
}
#endregion
#region API定义
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ChangeServiceConfig2(IntPtr serviceHandle, uint infoLevel, ref SERVICE_DESCRIPTION serviceDesc);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr OpenSCManager(string machineName, string databaseName, int dwDesiredAccess);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, int dwDesiredAccess);
[DllImport("advapi32.dll")]
public static extern int StartService(IntPtr SVHANDLE, int dwNumServiceArgs, string lpServiceArgVectors);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, int dwDesiredAccess, int dwServiceType, ServiceStartType dwStartType, int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CloseServiceHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool QueryServiceStatus(IntPtr hService, ref SERVICE_STATUS lpServiceStatus);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool DeleteService(IntPtr serviceHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ControlService(IntPtr hService, int dwControl, ref SERVICE_STATUS lpServiceStatus);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool EnumDependentServices(IntPtr serviceHandle, EnumServiceState serviceState, IntPtr bufferOfENUM_SERVICE_STATUS, int bufSize, ref int bytesNeeded, ref int numEnumerated);
#endregion
}
#endregion
/// <summary>
/// 服务状态枚举。用于遍历从属服务API
/// </summary>
public enum EnumServiceState
{
Active = 1,
InActive = 2,
All = 3
}
/// <summary>
/// 服务状态
/// </summary>
public enum ServiceState
{
Stopped = 1,
StartPending = 2,
StopPending = 3,
Running = 4,
ContinuePending = 5,
PausePending = 6,
Paused = 7
}
}
4.主界面代码
public partial class Main : Form
{
//声明委托 和 事件
public delegate void TransfDelegate();
public event TransfDelegate TransfEvent;
private frmConfig FrmConfig;//服务配置窗体
private frmITMSSetting FrmITMSSetting;//ITMS服务配置窗体
private frmAbout FrmAbout;//关于窗体
private static bool startFlag = true;
Dictionary<string, DateTime> dictimer = new Dictionary<string, DateTime>();
private Core.BLL.S_ServiceSetting _serviceSetting = new Core.BLL.S_ServiceSetting();
private Core.BLL.S_FieldContent _fieldContent = new Core.BLL.S_FieldContent();
private Core.BLL.S_ServiceConfig _serviceConfig = new Core.BLL.S_ServiceConfig();
#region 表单操作
/// <summary>
/// 控件字典
/// </summary>
private Dictionary<string, Control> dicControl;
private Dictionary<string, Control> DicControl
{
get
{
if (dicControl == null)
{
dicControl = new Dictionary<string, Control>();
foreach (Control control in this.ControlList)
{
if (control.Tag != null)
{
string name = control.Tag.ToString();
dicControl.Add(name, control);
}
}
}
return dicControl;
}
}
/// <summary>
/// 窗体所有控件集合
/// </summary>
private List<Control> ControlList
{
get
{
List<Control> controlList = new List<Control>();
this.GetControls(this.Controls, controlList);
return controlList;
}
}
/// <summary>
/// 递归获取所有控件
/// </summary>
private void GetControls(Control.ControlCollection controls, List<Control> controlList)
{
foreach (Control control in controls)
{
controlList.Add(control);
if (control.HasChildren)
{
GetControls(control.Controls, controlList);
}
}
}
private string GetConValue(Control control)
{
string conValue = string.Empty;
if (control.GetType() == typeof(CheckBox))
{
CheckBox cb = control as CheckBox;
conValue = cb.Checked.ToString();
}
else if (control.GetType() == typeof(RadioButton))
{
RadioButton rb = control as RadioButton;
conValue = rb.Checked.ToString();
}
else if (control.GetType() == typeof(TextBox))
{
TextBox tb = control as TextBox;
conValue = tb.Text.Trim();
}
else if (control.GetType() == typeof(ComboBox))
{
ComboBox cb = control as ComboBox;
conValue = cb.Text.ToString();
}
else if (control.GetType() == typeof(Label))
{
Label label = control as Label;
conValue = label.Text;
}
else if (control.GetType() == typeof(NumericUpDown))
{
NumericUpDown numericUpDown = control as NumericUpDown;
conValue = numericUpDown.Value.ToString();
}
return conValue;
}
#endregion
public Main()
{
InitializeComponent();
//订阅自定义事件
ServiceManageTool.Helper.WindowHelper.eventSend += new Helper.WinHandler(ReceiveParam);
}
private void Form1_Load(object sender, EventArgs e)
{
loadAppConfig();
loadAppList();
ServiceConfig helper = ServiceConfig.GetInstance();
helper.AutoMinAfterStart(this);
startFlag = false;
}
#region 监听事件
//监听事件
void ReceiveParam(object sender, object msg)
{
Type t = msg.GetType();
if (t.IsEnum)
{
eFrom e = (eFrom)msg;
switch (e)
{
case eFrom.Show_About:
ShowAboutFrm();
break;
case eFrom.Show_Main:
break;
case eFrom.Show_Config:
ShowConfigFrm((Core.Model.S_ServiceSetting)sender);
break;
case eFrom.Show_ItmsSetting:
ShowITMSConfigFrm((Core.Model.S_ServiceSetting)sender);
break;
}
}
}
#endregion
private void loadAppConfig()
{
List<Core.Model.S_ServiceConfig> configs = _serviceConfig.GetList(" ServiceId =0 and SettingType=1");
foreach (Core.Model.S_ServiceConfig config in configs)
{
if (DicControl.ContainsKey(config.ConName))
{
Control c = DicControl[config.ConName];
if (c.GetType() == typeof(CheckBox))
{
CheckBox cb = c as CheckBox;
cb.Checked = Convert.ToBoolean(config.ConValue);
}
else if (c.GetType() == typeof(RadioButton))
{
RadioButton rb = c as RadioButton;
rb.Checked = Convert.ToBoolean(config.ConValue);
}
else if (c.GetType() == typeof(TextBox))
{
TextBox tb = c as TextBox;
tb.Text = config.ConValue;
}
else if (c.GetType() == typeof(Label))
{
Label label = c as Label;
label.Text = config.ConValue;
}
else if (c.GetType() == typeof(NumericUpDown))
{
NumericUpDown numericUpDown = c as NumericUpDown;
numericUpDown.Value = config.ConValue.ToInt();
}
}
}
}
private void loadAppList()
{
listViewFiles.Items.Clear();
List<Core.Model.S_ServiceSetting> list = new List<Core.Model.S_ServiceSetting>();
list = _serviceSetting.GetList("");
foreach(Core.Model.S_ServiceSetting serviceInfo in list)
{
ListViewItem item = new ListViewItem { ImageIndex = 2, Text = serviceInfo.ServiceName };
item.Tag = serviceInfo;
item.SubItems.Add(serviceInfo.DisplayName);//显示名称
item.SubItems.Add("");//服务状态
item.SubItems.Add(serviceInfo.StartupType==1?"自动":"手动");//启动类型
item.SubItems.Add(serviceInfo.RunDuty==1?"启用":"停用");//运行值守
item.SubItems.Add(serviceInfo.DutyCycle.ToString()+"秒");//值守周期
item.SubItems.Add(serviceInfo.OperationList[serviceInfo.Operation.ToInt()]);//用户操作
listViewFiles.Items.Add(item);
}
}
#region 委托显示添加服务窗体
#region 服务创建
delegate void ShowConfigFrmEventHandler(Core.Model.S_ServiceSetting serviceInfo);
private void ShowConfigFrm(Core.Model.S_ServiceSetting serviceInfo)
{
if (this.InvokeRequired)
{
ShowConfigFrmEventHandler cb = new ShowConfigFrmEventHandler(ShowConfigFrm);
this.Invoke(cb, new object[] { });
}
else
{
if (FrmConfig == null || FrmConfig.IsDisposed)
{
FrmConfig = new frmConfig(serviceInfo);
FrmConfig.TransfEvent += LoadConfig;
FrmConfig.ShowDialog();
}
else
{
FrmConfig.Activate();
FrmConfig.TransfEvent += LoadConfig;
FrmConfig.ShowDialog();
}
}
}
#endregion
#region ITMS配置
delegate void ShowITMSConfigFrmEventHandler(Core.Model.S_ServiceSetting serviceInfo);
private void ShowITMSConfigFrm(Core.Model.S_ServiceSetting serviceInfo)
{
if (this.InvokeRequired)
{
ShowITMSConfigFrmEventHandler cb = new ShowITMSConfigFrmEventHandler(ShowITMSConfigFrm);
this.Invoke(cb, new object[] { });
}
else
{
if (FrmITMSSetting == null || FrmITMSSetting.IsDisposed)
{
FrmITMSSetting = new frmITMSSetting(serviceInfo);
FrmITMSSetting.TransfEvent += LoadConfig;
FrmITMSSetting.ShowDialog();
}
else
{
FrmITMSSetting.Activate();
FrmITMSSetting.TransfEvent += LoadConfig;
FrmITMSSetting.ShowDialog();
}
}
}
#endregion
#region 友情链接
delegate void ShowAboutFrmEventHandler();
private void ShowAboutFrm()
{
if (this.InvokeRequired)
{
ShowAboutFrmEventHandler cb = new ShowAboutFrmEventHandler(ShowAboutFrm);
this.Invoke(cb, new object[] { });
}
else
{
if (FrmAbout == null || FrmAbout.IsDisposed)
{
FrmAbout = new frmAbout();
FrmAbout.ShowDialog();
}
else
{
FrmAbout.Visible = true;
FrmAbout.Activate();
//FrmAbout.ShowDialog();
}
}
}
#endregion
#endregion
private void LoadConfig(object sender)
{
loadAppList();
}
#region 事件
/// <summary>
/// 创建服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_CreateService_Click(object sender, EventArgs e)
{
Helper.WindowHelper.WinHandler(null, eFrom.Show_Config);
}
/// <summary>
/// 更新服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_UpdateService_Click(object sender, EventArgs e)
{
try
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
Helper.WindowHelper.WinHandler(listViewItem.Tag, eFrom.Show_Config);
}
else
{
MessageBox.Show("请选择要变更的服务", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show("更新服务异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 删除服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_DelService_Click(object sender, EventArgs e)
{
try
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
if (MessageBox.Show(
"确定要删除选择的应用程序吗?",
"提示",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question) == DialogResult.Cancel)
{
return;
}
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
bool reslut = _serviceSetting.Delete(serviceInfo.Id);
if (reslut)
{
ServiceHelper.Uninstall(serviceInfo.ServiceName);
loadAppList();
}
}
else
{
MessageBox.Show("请选择要删除的服务", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show("删除服务异常:"+ex.Message,"系统错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
/// <summary>
/// 关于
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_About_Click(object sender, EventArgs e)
{
Helper.WindowHelper.WinHandler(null, eFrom.Show_About);
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Start_Click(object sender, EventArgs e)
{
try
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
//启动服务
var isok = ServiceHelper.StartService(serviceInfo.ServiceName, TimeSpan.FromSeconds(30));
if (isok)
{
serviceInfo.Operation = 2;
_serviceSetting.UpdateStatus(serviceInfo);
listViewItem.SubItems[6].Text = serviceInfo.OperationList[serviceInfo.Operation.ToInt()];
btn_Config.Enabled = true;
btn_Start.Enabled = true;
btn_UpdateService.Enabled = true;
btn_DelService.Enabled = true;
btn_Stop.Enabled = false;
}
}
else
{
MessageBox.Show("请选择要启动的服务", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show("启动服务异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 停止服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Stop_Click(object sender, EventArgs e)
{
try
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
//停止服务
var isok = ServiceHelper.StopService(serviceInfo.ServiceName, TimeSpan.FromSeconds(30));
if(isok)
{
serviceInfo.Operation = 3;
_serviceSetting.UpdateStatus(serviceInfo);
listViewItem.SubItems[6].Text = serviceInfo.OperationList[serviceInfo.Operation.ToInt()];
btn_Config.Enabled = false;
btn_Start.Enabled = false;
btn_UpdateService.Enabled = false;
btn_DelService.Enabled = false;
btn_Stop.Enabled = true;
}
}
else
{
MessageBox.Show("请选择要停止的服务", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show("停止服务异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 配置服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Config_Click(object sender, EventArgs e)
{
try
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
Core.Model.S_ServiceConfig config = _serviceConfig.GetByConName("ServiceType", serviceInfo.Id, 2);
//----
List<Core.Model.S_FieldContent> list = _fieldContent.GetModelList("ServiceType");
Core.Model.S_FieldContent fieldModel = list.Find(e => e.FieldContent == config.ConValue);
switch (fieldModel.Code)
{
case "1":
Helper.WindowHelper.WinHandler(listViewItem.Tag, eFrom.Show_ItmsSetting);
break;
case "2":
break;
default:
break;
}
}
else
{
MessageBox.Show("请选择要配置的服务", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show("配置服务异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
void showMain()
{
this.Visible = true;
this.WindowState = System.Windows.Forms.FormWindowState.Normal;
this.ShowInTaskbar = true;
}
private void NIMin_MouseDoubleClick(object sender, MouseEventArgs e)
{
showMain();
}
/// <summary>
/// 最小化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Main_MinimumSizeChanged(object sender, EventArgs e)
{
if (startFlag)
{
return;
}
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
this.NIMin.Visible = true;
this.ShowInTaskbar = false;
}
}
/// <summary>
/// 定时器事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TimerCheckStatus_Tick(object sender, EventArgs e)
{
if (startFlag)
{
return;
}
try
{
if (listViewFiles.Items.Count > 0)
{
bool isStart = false;
string name = string.Empty;
foreach (ListViewItem listViewItem in listViewFiles.Items)
{
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
name = serviceInfo.ServiceName;
isStart = SystemHelper.CheckServiceStatus(name);
if (isStart)
{
listViewItem.ImageIndex = 1;
listViewItem.SubItems[2].Text = "正在运行";
}
else
{
if (dictimer.ContainsKey(name))
{
DateTime beginTime = dictimer[name];
TimeSpan timeSpan = DateTime.Now - beginTime;
if (serviceInfo.RunDuty > 0)
{
Int64 isRun = timeSpan.TotalSeconds.ToInt64() % serviceInfo.DutyCycle.ToInt64();
if (isRun == 0)
{
bool status = ServiceHelper.StartService(serviceInfo.ServiceName, TimeSpan.FromSeconds(30));
if (status)
{
dictimer.Remove(name);
listViewItem.ImageIndex = 1;
listViewItem.SubItems[2].Text = "正在运行";
}
else
{
listViewItem.ImageIndex = 2;
listViewItem.SubItems[2].Text = "已停止";
}
}
else
{
listViewItem.ImageIndex = 2;
listViewItem.SubItems[2].Text = "已停止";
}
}
else
{
listViewItem.ImageIndex = 2;
listViewItem.SubItems[2].Text = "已停止";
}
}
else
{
dictimer.Add(name, DateTime.Now);
listViewItem.ImageIndex = 2;
listViewItem.SubItems[2].Text = "已停止";
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("服务值守异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 自动启动选择事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void checkAuto_CheckedChanged(object sender, EventArgs e)
{
if (startFlag)
{
return;
}
try
{
Control control = checkAuto;
Core.Model.S_ServiceConfig config = new Core.Model.S_ServiceConfig();
config.ConName = control.Tag.ToString();
config.ConType = control.GetType().Name;
config.ConValue = GetConValue(control);
config.ServiceId = 0;
config.SettingType = 1;
_serviceConfig.Save(config);
ServiceConfig helper = ServiceConfig.GetInstance();
helper.AutoStart();
}
catch (Exception ex)
{
MessageBox.Show("设置随系统自动启动异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 设置托盘选择事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void checkTuopan_CheckedChanged(object sender, EventArgs e)
{
if (startFlag)
{
return;
}
try
{
Control control = checkTuopan;
Core.Model.S_ServiceConfig config = new Core.Model.S_ServiceConfig();
config.ConName = control.Tag.ToString();
config.ConType = control.GetType().Name;
config.ConValue = GetConValue(control);
config.ServiceId = 0;
config.SettingType = 1;
_serviceConfig.Save(config);
ServiceConfig helper = ServiceConfig.GetInstance();
helper.AutoMinAfterStart(this);
}
catch (Exception ex)
{
MessageBox.Show("设置启动后托盘运行异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 列表选择事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void listViewFiles_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem listViewItem = new ListViewItem();
if (listViewFiles.SelectedIndices != null && listViewFiles.SelectedIndices.Count > 0)
{
ListView.SelectedIndexCollection c = listViewFiles.SelectedIndices;
listViewItem = listViewFiles.Items[c[0]];
if (listViewItem.ImageIndex == 1)
{
btn_Config.Enabled = false;
btn_Start.Enabled = false;
btn_UpdateService.Enabled = false;
btn_DelService.Enabled = false;
btn_Stop.Enabled = true;
}
else
{
btn_Config.Enabled = true;
btn_Start.Enabled = true;
btn_UpdateService.Enabled = true;
btn_DelService.Enabled = true;
btn_Stop.Enabled = false;
}
}
}
private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
this.NIMin.Visible = true;
this.ShowInTaskbar = false;
e.Cancel=true;
}
/// <summary>
/// 显示主页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmMain_Click(object sender, EventArgs e)
{
showMain();
}
/// <summary>
/// 关于
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void About_Click(object sender, EventArgs e)
{
Helper.WindowHelper.WinHandler(null, eFrom.Show_About);
}
/// <summary>
/// 退出,停止所有服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Logout_Click(object sender, EventArgs e)
{
try
{
if (listViewFiles.Items.Count > 0)
{
bool isStart = false;
string name = string.Empty;
foreach (ListViewItem listViewItem in listViewFiles.Items)
{
Core.Model.S_ServiceSetting serviceInfo = (Core.Model.S_ServiceSetting)listViewItem.Tag;
name = serviceInfo.ServiceName;
isStart = SystemHelper.CheckServiceStatus(name);
if (isStart)
{
var isok = ServiceHelper.StopService(name, TimeSpan.FromSeconds(30));
}
}
}
this.Close();
this.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("退出服务管理器异常:" + ex.Message, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
}
以上代码段为系统主要核心代码,部分代码来源于公开网络。
结束
由于时间关系,先介绍到这里,有喜欢的朋友可以联系我索取源码与应用。