注意點:
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,點擊安裝按鈕,即可看到效果。
-