C#.NET 操作Windows服務(安裝、卸載)


注意點:

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

 

 

 

 

-


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM