C#開發Windows服務詳細流程

撈月亮的猴子發表於2018-12-28

1.Windows服務簡單介紹

  Windows服務程式是在Windows作業系統下能完成特定功能的可執行的應用程式,主要用於長時間執行的功能或者執行定時任務。一般情況下,使用者不能通過使用者介面來安裝和啟動Windows服務程式,服務的啟動方式有自動啟動和手動啟動兩種。我們可以在執行中輸入services.msc 命令開啟服務管理介面,在這裡可以進行啟動或者停止服務:

2.C#開發windows服務

1.windows服務開發流程

1.1 windows的基本開發流程

  使用.Net可以很方便地開發windows服務,下邊通過一個栗子演示下開發windows服務的簡單流程。

  首先建立一個Windows服務專案,如下圖我們建立了一個叫MyService的服務專案

  然後開啟自動生成的Service1.cs,該檔案預設有兩個方法: OnStart()和OnStop() ,OnStart()指定當服務啟動時要執行的操作,OnStop()指定當服務停止時要執行的操作。 我們重寫OnStart()方法,讓服務開啟的時候,每隔一秒在一個文字檔案中記錄當前時間,程式碼如下圖

然後在右鍵Service1.cs檔案,選擇檢視設計器,在介面上右鍵選擇新增安裝程式,如下圖

修改serviceInstallerserviceProcessInstaller,如下圖所示,到這裡服務的建立工作就完成了

1.2 安裝和解除安裝Windows服務專案

   我們先通過下邊命令來安裝和解除安裝服務,其中第二行命令用於安裝服務,命令的地址是我們服務專案生成的exe檔案所在路徑,第三行命令用於解除安裝服務。

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

InstallUtil C:\Users\ZDZN\source\repos\WindowsServiceDemo\WindowsServiceInstall\bin\Debug\MyService.exe    ----------安裝服務
InstallUtil -u C:\Users\ZDZN\source\repos\WindowsServiceDemo\WindowsServiceInstall\bin\Debug\MyService.exe ----------解除安裝服務

執行成功後在服務管理介面可以看到我們剛才安裝的服務,這說明服務已經安裝成功了:

我們可以在命令列中通過以下命令控制服務的開啟和停止:

net start MyService //開啟服務
net stop MyService //停止服務

如果程式沒有錯誤的話,服務啟動後會在F盤中生成一個hello.txt檔案,內容如下:

2.通過Winform控制windows服務

  雖然通過命令列可以實現Windows服務的安裝、解除安裝、啟動、停止等操作,但是這樣對於使用者來說還是太過麻煩。如果能通過Winform來實現這些功能,使用者使用起來就方便多了。怎麼讓Winform控制windows服務呢?

首先要知道的一些知識:使用AssemblyInstaller可以進行Windows服務的安裝和解除安裝,ServiceController可以控制windows服務的啟動,停止,暫停,繼續等,知道了這些就容易實現了。

新增一個winform應用程式,引用我們的服務專案,程式程式碼如下,這裡的命名都很明顯就不詳細說明:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //設定服務地址和服務名
        string serviceFilePath = $"{Application.StartupPath}/MyService.exe";
        string serviceName = "MyService";

        private void btnInstall_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                ShowMessage("開始安裝服務...");
                if (IsServiceExisted(serviceName))
                {
                    UninstallService(serviceFilePath);
                }
                InstallService(serviceFilePath);
            });
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                ShowMessage("服務正在啟動...");
                if (IsServiceExisted(serviceName))
                {
                    ServiceStart(serviceName);
                    ShowMessage("服務已啟動");
                }

            });
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                ShowMessage("服務正在停止...");
                if (IsServiceExisted(serviceName))
                {
                    ServiceStop(serviceName);
                    ShowMessage("服務已停止");
                }
            });
        }



        private void btnUninstall_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                ShowMessage("開始解除安裝服務...");
                if (this.IsServiceExisted(serviceName))
                {
                    this.ServiceStop(serviceName);
                }
                this.UninstallService(serviceFilePath);
            });
        }

        #region 方法封裝
        private void ShowMessage(string s)
        {
            Action setState = () =>
            {
                myTxtBox.AppendText(DateTime.Now.ToString("f") + "");
                myTxtBox.AppendText(Environment.NewLine);
                myTxtBox.AppendText(s);
                myTxtBox.AppendText(Environment.NewLine);

            };
            myTxtBox.Invoke(setState);
        }

        //判斷服務是否存在
        private bool IsServiceExisted(string serviceName)
        {
            try
            {
                ServiceController[] services = ServiceController.GetServices();
                foreach (ServiceController sc in services)
                {
                    if (sc.ServiceName.ToLower() == serviceName.ToLower())
                    {
                        return true;
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                return false;
            }
        }

        //安裝服務
        private void InstallService(string serviceFilePath)
        {
            try
            {
                using (AssemblyInstaller installer = new AssemblyInstaller())
                {
                    installer.UseNewContext = true;
                    installer.Path = serviceFilePath;
                    IDictionary savedState = new Hashtable();
                    installer.Install(savedState);
                    installer.Commit(savedState);
                    ShowMessage("服務安裝完成");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
            }
        }

        //解除安裝服務
        private void UninstallService(string serviceFilePath)
        {
            try
            {
                using (AssemblyInstaller installer = new AssemblyInstaller())
                {
                    installer.UseNewContext = true;
                    installer.Path = serviceFilePath;
                    installer.Uninstall(null);
                    ShowMessage("服務解除安裝完成");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
            }
        }

        //啟動服務
        private void ServiceStart(string serviceName)
        {
            try
            {
                using (ServiceController control = new ServiceController(serviceName))
                {
                    if (control.Status == ServiceControllerStatus.Stopped)
                    {
                        control.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
            }
        }


        //停止服務
        private void ServiceStop(string serviceName)
        {
            try
            {
                using (ServiceController control = new ServiceController(serviceName))
                {
                    if (control.Status == ServiceControllerStatus.Running)
                    {
                        control.Stop();
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
            }
        }
        #endregion

        #region 頁面元素

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;

            timer1.Interval = 100;
            timer1.Enabled = true;
        }

        //btn狀態
        private void ButtonState()
        {
            if (IsServiceExisted(serviceName))
            {
                btnInstall.Enabled = false;
                btnUninstall.Enabled = true;
                using (var service = new ServiceController(serviceName))
                {
                    if (service.Status == ServiceControllerStatus.Running || service.Status == ServiceControllerStatus.StartPending)
                    {
                        btnUninstall.Enabled = false;
                        btnStart.Enabled = false;
                        btnStop.Enabled = true;
                    }
                    else
                    {
                        btnUninstall.Enabled = true;
                        btnStart.Enabled = true;
                        btnStop.Enabled = false;
                    }
                }
            }
            else
            {
                btnInstall.Enabled = true;
                btnUninstall.Enabled = false;
                btnStart.Enabled = false;
                btnStop.Enabled = false;
            }
        }
        //底部label狀態
        private void LabelState()
        {
            if (!IsServiceExisted(serviceName))
            {
                this.labState.Text = $"【{serviceName}】服務未安裝";
                return;
            }
            using (var service = new ServiceController(serviceName))
            {
                switch (service.Status)
                {
                    case ServiceControllerStatus.Running:
                        this.labState.Text = $"【{serviceName}】服務已啟動";
                        break;
                    case ServiceControllerStatus.StartPending:
                        this.labState.Text = $"【{serviceName}】服務正在啟動...";
                        break;
                    case ServiceControllerStatus.Stopped:
                        this.labState.Text = $"【{serviceName}】服務已停止";
                        break;
                    case ServiceControllerStatus.StopPending:
                        this.labState.Text = $"【{serviceName}】服務正在停止...";
                        break;
                    default:
                        break;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            ButtonState();
            LabelState();
        }
        #endregion
    }
View Code

完成這一步後,我們就可以通過視覺化介面對服務的安裝,解除安裝,執行,停止進行控制了。

補充:使用TopShelf也可以實現Windows服務的快速開發,參考文件 http://docs.topshelf-project.com/en/latest/index.html

 

相關文章