1. 程式人生 > >使用C#建立windows服務

使用C#建立windows服務

前言:

前段時間因為專案上需要用到實現一個簡答的衛星雲圖播放功能,因此需要將衛星雲圖實時下載到本地目錄。當時也沒多想,直接就用控制檯程式開發了一個衛星雲圖自動下載工具。最近專案不是很忙了,靜下心重新看了一下專案程式碼,對部分程式碼進行了重構......

同時也發現了衛星雲圖下載工具的問題,總不能每次客戶使用的時候都讓客戶去跑一遍控制檯程式或者一直執行這個控制檯程式吧。於是打算把衛星雲圖下載工具寫成服務的形式,這樣就不用擔心衛星雲圖的實時性了。

說幹就幹!

開發環境:

作業系統:Windows 10 X64

開發環境:VS2017

程式語言:C#

.NET版本:.NET Framework 4.5

目標平臺:X86

Windows Service簡介:

一個Windows服務程式是在Windows作業系統下能完成特定功能的可執行的應用程式。Windows服務程式雖然是可執行的,但是它不像一般的可執行檔案通過雙擊就能開始運行了,它必須有特定的啟動方式。這些啟動方式包括了自動啟動和手動啟動兩種。對於自動啟動的Windows服務程式,它們在Windows啟動或是重啟之後使用者登入之前就開始執行了。只要你將相應的Windows服務程式註冊到服務控制管理器(Service Control Manager)中,並將其啟動類別設為自動啟動就行了。而對於手動啟動的Windows服務程式,你可以通過命令列工具的NET START

 命令來啟動它,或是通過控制面板中管理工具下的服務一項來啟動相應的Windows服務程式。

同樣,一個Windows服務程式也不能像一般的應用程式那樣被終止。因為Windows服務程式一般是沒有使用者介面的,所以你也要通過命令列工具或是下面圖中的工具來停止它,或是在系統關閉時使得Windows服務程式自動停止。因為Windows服務程式沒有使用者介面,所以基於使用者介面的API函式對其是沒有多大的意義。為了能使一個Windows服務程式能夠正常並有效的在系統環境下工作,程式設計師必須實現一系列的方法來完成其服務功能。Windows服務程式的應用範圍很廣,典型的Windows服務程式包含了硬體控制、應用程式監視、系統級應用、診斷、報告、Web和檔案系統服務等功能。

使用C#開發Windows服務的步驟:

1.建立Windows Service專案

從Visual Studio 2017 工程中選取 Windows 服務(Windows Service)選項,給工程一個新檔名,然後點選 確定

建立後的專案如下圖所示:

2.找到目錄結構中的OnStart函式和OnStop函式,OnStart函式在啟動服務時執行,OnStop函式在停止服務時執行

protected override void OnStart(string[] args)
        {
            StartLoad();
        }

        protected override void OnStop()
        {
            _Timer.Stop();
        }
StartLoad核心程式碼如下:
CreateFilePath();//判斷資料夾是否存在,不存在則建立
            //獲取前一天日期
            string lastYear = DateTime.Now.AddDays(-1).Year.ToString();
            string lastMonth = DateTime.Now.AddDays(-1).Month.ToString();
            if (lastMonth.Length < 2) lastMonth = "0" + lastMonth;
            string lastDay = DateTime.Now.AddDays(-1).Day.ToString();
            if (lastDay.Length < 2) lastDay = "0" + lastDay;
            //獲取當天日期
            string year = DateTime.Now.Year.ToString();
            string month = DateTime.Now.Month.ToString();
            if (month.Length < 2) month = "0" + month;
            string day = DateTime.Now.Day.ToString();
            if (day.Length < 2) day = "0" + day;
            //設定所有檔名
            string[] dates0 = { lastYear + "/" + lastMonth + "/" + lastDay, year + "/" + month + "/" + day };
            string[] dates = { lastYear + lastMonth + lastDay, year + month + day };
            string[] hours = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" };
            string[] minutes = { "15", "45" };
            int hLength = hours.Count();
            //遍歷下載當天所有線上雲圖
            for (int i = 0; i < 2; i++)
            {
                string date = dates[i];
                string date0 = dates0[i];
                for (int j = 0; j < hLength; j++)
                {
                    string hour = hours[j];
                    for (int k = 0; k < 2; k++)
                    {
                        string minute = minutes[k];
                        string imageUrl = @"http://image.nmc.cn/product/" + date0 + @"/WXCL/SEVP_NSMC_WXCL_ASC_E99_ACHN_LNO_PY_" + date + hour + minute + "00000.JPG";
                        string[] s = imageUrl.Split('/');
                        string imageName = s[s.Count() - 1];

                        HttpWebRequest request = HttpWebRequest.Create(imageUrl) as HttpWebRequest;
                        HttpWebResponse response = null;
                        try
                        {
                            response = request.GetResponse() as HttpWebResponse;
                        }
                        catch (Exception)
                        {
                            continue;
                        }

                        if (response.StatusCode != HttpStatusCode.OK) continue;
                        Stream reader = response.GetResponseStream();
                        FileStream writer = new FileStream(_ImagePath + imageName, FileMode.OpenOrCreate, FileAccess.Write);
                        byte[] buff = new byte[512];
                        int c = 0; //實際讀取的位元組數
                        while ((c = reader.Read(buff, 0, buff.Length)) > 0)
                        {
                            writer.Write(buff, 0, c);
                        }
                        writer.Close();
                        writer.Dispose();
                        reader.Close();
                        reader.Dispose();
                        response.Close();
                    }
                }
            }

因為要實現衛星雲圖的實時性,所以我用了Timer計時器來設定每隔30分鐘下載一次,程式碼很簡單,相信大神們都會,這裡就不寫了!

安裝服務步驟:

1.開啟設計介面,右鍵選擇“新增安裝程式”,如圖所示:

介面上會出現serviceInstaller1和serviceProcessInstaller1

修改serviceInstaller1屬性,將StartType修改為Automatic,ServiceName改為CloudImageLoad,同時可以新增Description屬性,也就是你的windows服務的描述資訊(建議新增)

修改serviceProcessInstaller1屬性,將Account屬性改為LocalSystem

2.進行服務的安裝以“管理員身份”開啟VS2017命令提示符工具,記住一定要以管理員身份執行

隨後通過命令cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319進入檔案目錄

通過命令installutil D:\軟體開發\CloudImageLoad\CloudImageLoad\bin\Debug\CloudImageLoad.exe 完成服務的安裝

“D:\軟體開發\CloudImageLoad\CloudImageLoad\bin\Debug\CloudImageLoad.exe”及為你專案生成的路徑

檢視服務列表,此時就可以看到服務已經在服務列表中了

第一次安裝的服務應該是沒有執行的,需要手動啟動一下!

服務的解除安裝命令:installutil /u D:\軟體開發\CloudImageLoad\CloudImageLoad\bin\Debug\CloudImageLoad.exe 

  • 補充:

1.Service啟動屬性:

        Manual      服務安裝後,必須手動啟動。

        Automatic    每次計算機重新啟動時,服務都會自動啟動。

        Disabled     服務無法啟動。

2.新建的Service專案,其中各屬性的含義(設計檢視->右鍵屬性):

  Autolog 是否自動寫入系統的日誌檔案

  CanHandlePowerEvent 服務時候接受電源事件

  CanPauseAndContinue 服務是否接受暫停或繼續執行的請求

  CanShutdown 服務是否在執行它的計算機關閉時收到通知,以便能夠呼叫 OnShutDown 過程

  CanStop 服務是否接受停止執行的請求

  ServiceName 服務名

參考連結:

https://www.cnblogs.com/bluestorm/p/3510398.html

https://www.cnblogs.com/cncc/p/7170951.html