前言
在我們的工作中,經常遇到Windows服務的安裝和卸載,在之前公司也普寫過一個WinForm程序選擇安裝路徑,這次再來個小巧靈活的控制臺程序,不用再選擇,只需放到需要安裝服務的目錄中運行就可以實現安裝或卸載。
開發思路
1、由于系統的權限限制,在運行程序時需要以管理員身份運行
2、因為需要實現安裝和卸載兩個功能,在程序運行時提示本次操作是安裝還是卸載 需要輸入 1 或 2
3、接下來程序會查找當前目錄中的可執行文件并過濾程序本身和有時我們復制進來的帶有vhost的文件,并列出列表讓操作者選擇(一般情況下只有一個)
4、根據用戶所選進行安裝或卸載操作
5、由于可能重復操作,需要遞歸調用一下
具體實現
首先們要操作服務,需要用 System.ServiceProcess 來封裝實現類
using System;using System.Collections;using System.Configuration.Install;using System.Linq;using System.ServiceProcess;namespace AutoInstallUtil{ public class SystemServices { /// <summary> /// 打開系統服務 /// </summary> /// <param name="serviceName">系統服務名稱</param> /// <returns></returns> public static bool SystemServiceOpen(string serviceName) { try { using (var control = new ServiceController(serviceName)) { if (control.Status != ServiceControllerStatus.Running) { control.Start(); } } return true; } catch { return false; } } /// <summary> /// 關閉系統服務 /// </summary> /// <param name="serviceName">系統服務名稱</param> /// <returns></returns> public static bool SystemServiceClose(string serviceName) { try { using (var control = new ServiceController(serviceName)) { if (control.Status == ServiceControllerStatus.Running) { control.Stop(); } } return true; } catch { return false; } } /// <summary> /// 重啟系統服務 /// </summary> /// <param name="serviceName">系統服務名稱</param> /// <returns></returns> public static bool SystemServiceReStart(string serviceName) { try { using (var control = new ServiceController(serviceName)) { if (control.Status == System.ServiceProcess.ServiceControllerStatus.Running) { control.Continue(); } } return true; } catch { return false; } } /// <summary> /// 返回服務狀態 /// </summary> /// <param name="serviceName">系統服務名稱</param> /// <returns>1:服務未運行 2:服務正在啟動 3:服務正在停止 4:服務正在運行 5:服務即將繼續 6:服務即將暫停 7:服務已暫停 0:未知狀態</returns> public static int GetSystemServiceStatus(string serviceName) { try { using (var control = new ServiceController(serviceName)) { return (int)control.Status; } } catch { return 0; } } /// <summary> /// 返回服務狀態 /// </summary> /// <param name="serviceName">系統服務名稱</param> /// <returns>1:服務未運行 2:服務正在啟動 3:服務正在停止 4:服務正在運行 5:服務即將繼續 6:服務即將暫停 7:服務已暫停 0:未知狀態</returns> public static string GetSystemServiceStatusString(string serviceName) { try { using (var control = new ServiceController(serviceName)) { var status = string.Empty; switch ((int)control.Status) { case 1: status = "服務未運行"; break; case 2: status = "服務正在啟動"; break; case 3: status = "服務正在停止"; break; case 4: status = "服務正在運行"; break; case 5: status = "服務即將繼續"; break; case 6: status = "服務即將暫停"; break; case 7: status = "服務已暫停"; break; case 0: status = "未知狀態"; break; } return status; } } catch { return "未知狀態"; } } /// <summary> /// 安裝服務 /// </summary> /// <param name="stateSaver"></param> /// <param name="filepath"></param> public static void InstallService(IDictionary stateSaver, string filepath) { try { var myAssemblyInstaller = new AssemblyInstaller { UseNewContext = true, Path = filepath }; myAssemblyInstaller.Install(stateSaver); myAssemblyInstaller.Commit(stateSaver); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw new Exception("installServiceError/n" + ex.Message); } } public static bool ServiceIsExisted(string serviceName) { ServiceController[] services = ServiceController.GetServices(); return services.Any(s => s.ServiceName == serviceName); } /// <summary> /// 卸載服務 /// </summary> /// <param name="filepath">路徑和文件名</param> public static void UnInstallService(string filepath) { try { //UnInstall Service var myAssemblyInstaller = new AssemblyInstaller { UseNewContext = true, Path = filepath }; myAssemblyInstaller.Uninstall(null); myAssemblyInstaller.Dispose(); } catch (Exception ex) { throw new Exception("unInstallServiceError/n" + ex.Message); } } }}
接下來我們封裝控制臺的操作方法為了實現循環監聽這里用了遞歸
using System;using System.Diagnostics;using System.IO;using System.Linq;namespace AutoInstallUtil{ class Program { static void Main(string[] args) { try { ServerAction(); } catch (Exception ex) { Console.WriteLine("發生錯誤:{0}", ex.Message); } Console.ReadKey(); } /// <summary> /// 操作 /// </summary> private static void ServerAction() { Console.WriteLine("請輸入:1安裝 2卸載"); var condition = Console.ReadLine(); var currentPath = Environment.CurrentDirectory; var currentFileNameVshost = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName).ToLower(); var currentFileName = currentFileNameVshost.Replace(".vshost.exe", ".exe"); var files = Directory.GetFiles(currentPath) .Select(o => Path.GetFileName(o).ToLower()) .ToList() .Where( o => o != currentFileNameVshost && o != currentFileName && o.ToLower().EndsWith(".exe") && o != "installutil.exe" && !o.ToLower().EndsWith(".vshost.exe")) .ToList(); if (files.Count == 0) { Console.WriteLine("未找到可執行文件,請確認當前目錄有需要安裝的服務程序"); } else { Console.WriteLine("找到目錄有如下可執行文件,請選擇需要安裝或卸載的文件序號:"); } int i = 0; foreach (var file in files) { Console.WriteLine("序號:{0} 文件名:{1}", i, file); i++; } var serviceFileIndex = Console.ReadLine(); var servicePathName = currentPath + "http://" + files[Convert.ToInt32(serviceFileIndex)]; if (condition == "1") { SystemServices.InstallService(null, servicePathName); } else { SystemServices.UnInstallService(servicePathName); } Console.WriteLine("**********本次操作完畢**********"); ServerAction(); } }}
到此為止簡單的安裝程序就寫完了,為了醒目我選了個紅色的西紅柿來做為圖標,這樣顯示些
源碼和程序:安裝卸載Windows服務
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答