注意点:
1.安装时要请求到管理员权限。
2.卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑。代码无法停止服务时,使用services.msc来停止。
开始:
1。新建一个名为“Windows服务操作”的WINFORM程序。
2。在解决方案里添加一个Windows服务项目,名为“ADemoWinSvc”。
3。双击“Service1.cs”,右键,添加安装程序。
4。双击“ProjectInstaller.cs”,修改“serviceProcessInstaller1”中的“Account”为“LocalSystem”.
5。修改“serviceInstaller1”,"Description"设置为“这是一个demo windows服务”,ServiceName 设置为“ADemoWinSvc”,StartType 设置为“Automatic”。
6。修改“Service1.cs”的代码,增加服务启动日志和停止日志。
using CommonUtils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; namespace ADemoWinSvc { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { GLog.WLog("服务已启动"); } protected override void OnStop() { GLog.WLog("服务已停止"); } } }
工具类:
using System; using System.IO; namespace CommonUtils { public static class GLog { static object _lockObj = new object(); public static void WLog(string content) { lock (_lockObj) { string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName); string logDir = "Logs"; string logDirFullName = Path.Combine(curPath, logDir); try { if (!Directory.Exists(logDirFullName)) Directory.CreateDirectory(logDirFullName); } catch { return; } string fileName = "Logs" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt"; string logFullName = Path.Combine(logDirFullName, fileName); try { using (FileStream fs = new FileStream(logFullName, FileMode.Append, FileAccess.Write)) using (StreamWriter sw = new StreamWriter(fs)) sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + content); } catch { return; } } } } }
7。回到winform程序,在“Form1.cs”上添加“安装”和“卸载”2个按钮。
代码如下:
using CommonUtils; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; namespace Windows服务操作 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// windows服务名 /// </summary> static string _winSvcName = "ADemoWinSvc"; /// <summary> /// windows服务对应的exe 名 /// </summary> static string _winSvcExeName = "ADemoWinSvc.exe"; private void btnSetup_Click(object sender, EventArgs e) { try { //是否存在服务 if (ServiceUtil.ServiceIsExisted(_winSvcName)) { //已存在,检查是否启动 if (ServiceUtil.IsRun(_winSvcName)) { //服务是已启动状态 lblMsg.Text = "[001]服务是已启动状态"; } else { //未启动,则启动 ServiceUtil.StarService(_winSvcName); lblMsg.Text = "[002]服务是已启动状态"; } } else { //不存在,则安装 IDictionary mySavedState = new Hashtable(); string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName); string apppath = Path.Combine(curPath, _winSvcExeName); ServiceUtil.InstallService(mySavedState, apppath); lblMsg.Text = "[003]服务是已启动状态"; //安装后并不会自动启动。需要启动这个服务 ServiceUtil.StarService(_winSvcName); lblMsg.Text = "[004]服务是已启动状态"; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btnUninstall_Click(object sender, EventArgs e) { //** 卸载服务最重要的是先停止,否则电脑需要重启或注销 ** try { //是否存在服务 if (!ServiceUtil.ServiceIsExisted(_winSvcName)) { MessageBox.Show("服务不存在,不需要卸载"); return; } //如果服务正在运行,停止它 if (ServiceUtil.IsRun(_winSvcName)) { ServiceUtil.StopService(_winSvcName); } //再检查一次是否在运行 if (ServiceUtil.IsRun(_winSvcName)) { MessageBox.Show("服务无法停止,请手动停止这个服务"); return; } //卸载 ServiceUtil.UnInstallServiceByName(_winSvcName); lblMsg.Text = "[005]服务已卸载"; } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }
使用到的工具类:
using System; using System.Collections; using System.Collections.Generic; using System.Configuration.Install; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; namespace CommonUtils { /// <summary> /// windows服务操作工具类 /// </summary> public static class ServiceUtil { /// <summary> /// 服务是否正在运行 /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool IsRun(string name) { bool IsRun = false; try { if (!ServiceIsExisted(name)) return false; var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.StartPending || sc.Status == ServiceControllerStatus.Running) { IsRun = true; } sc.Close(); } catch { IsRun = false; } return IsRun; } /// <summary> /// 启动服务 /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool StarService(string name) { try { var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.Stopped || sc.Status == ServiceControllerStatus.StopPending) { sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10)); } else { } sc.Close(); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 停止服务(有可能超时) /// </summary> /// <param name="name"></param> /// <returns></returns> public static bool StopService(string name) { try { var sc = new ServiceController(name); if (sc.Status == ServiceControllerStatus.Running || sc.Status == ServiceControllerStatus.StartPending) { sc.Stop(); //停止服务超时时间:56秒。 sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 56)); } else { } sc.Close(); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 是否存在 /// </summary> /// <param name="serviceName"></param> /// <returns></returns> public static bool ServiceIsExisted(string serviceName) { ServiceController[] services = ServiceController.GetServices(); foreach (ServiceController s in services) if (s.ServiceName.ToLower() == serviceName.ToLower()) return true; return false; } /// <summary> /// 安装 /// </summary> /// <param name="stateSaver"></param> /// <param name="filepath"></param> public static void InstallService(IDictionary stateSaver, string filepath) { try { AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller(); myAssemblyInstaller.UseNewContext = true; myAssemblyInstaller.Path = filepath; myAssemblyInstaller.Install(stateSaver); myAssemblyInstaller.Commit(stateSaver); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw ex; } } /// <summary> /// 使用路径卸载(有时候不便于用路径来卸载,则使用SC DELETE 名称来卸载) /// </summary> /// <param name="filepath"></param> public static void UnInstallService(string filepath) { try { AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller(); myAssemblyInstaller.UseNewContext = true; myAssemblyInstaller.Path = filepath; myAssemblyInstaller.Uninstall(null); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw ex; } } /// <summary> /// 使用windows服务名卸载 /// </summary> /// <param name="WinServiceName"></param> public static void UnInstallServiceByName(string WinServiceName) { ProcessStartInfo pStart = new ProcessStartInfo("sc.exe"); Process pRoc = new Process(); pStart.Arguments = " delete " + WinServiceName; pStart.UseShellExecute = false; pStart.CreateNoWindow = false; pRoc.StartInfo = pStart; pRoc.Start(); pRoc.WaitForExit(); } } }
winform 程序里要引用 System.Configuration.Install、System.ServiceProcess 这2个程序集。
8。分别编译ADemoWinSvc、Windows服务操作,将ADemoWinSvc.exe 复制到Windows服务操作.exe 所在目录。
9。管理员身份运行Windows服务操作.exe,点击安装按钮,即可看到效果。
-