最近在研究Windows Service
網路資料有些片段,寫個文章整理一下
主要目標很簡單,就是寫一個排程器
每隔幾秒做事情
放在伺服器上
-----
以下用visual studio 2012做示範
建立專案
一樣老樣子從開新專案開始
File -> New -> Project...
選Visual C# -> Windows -> Windows Service (中文叫做Windows服務)
然後打上專案名稱 (這裡用MyService1)
按下OK後建立
然後就建立專案
這裡可以發現這個Service的專案跟一般視窗專案有些不同
除了一樣有Program.cs
多了Service1.cs
點選Service1.cs在Design模式時,什麼都沒有(因為只有元件沒有畫面)
點選Click here to switch to code view直接看程式碼
這裡就有原始碼
只有很簡單的OnStart跟OnStop
因為它是服務,所以無法直接執行
直接按Start按鈕執行的話會看到這個視窗
意思是說,這服務需要被安裝才可以執行
需要用到 installutil.exe 這程式來安裝(等下再介紹)
然後還要用NET START指令啟動服務(這可以不用理會沒關係,我們可以用圖形介面)
---------
到這裡還沒有開始寫排程器,還要爲這個服務做一些設定
回到Service1.cs的Design模式(就是剛剛什麼都沒有地方)
按右鍵 -> Add Installer (加入安裝程式)
這時會多一個ProjectInstaller.cs檔案,在設計模式底下會有這二個東西
點選 serviceInstaller1
這裡需要做一些設定
DisplayName 就是服務要顯示的名稱
Description 服務描述
ServiceName 服務的唯一名稱
StartType 啓動方式,初始值爲Manual (手動)
當然要設定Automatic (自動) 呀
DelayedAutoStart 爲開機之後是否延遲啓動
點選 serviceProcessInstaller1
設定只要改一個
Account 這裡決定服務的帳號與權限
我們可以設定爲LocalSystem (就是最大權限)
---------
撰寫相關程式碼
先撰寫定時器
這裡用到 System.Timers 所以要先引用
using System.Timers;
然後寫一個定時器
private Timer MyTimer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
MyTimer = new Timer();
MyTimer.Elapsed += new ElapsedEventHandler(MyTimer_Elapsed);
MyTimer.Interval = 10 * 1000;
MyTimer.Start();
}
private void MyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
// Do SomeThing...
}
這裡設定 定時器為每10秒 執行一次
日誌輸出
在設計模式拉一個EventLog
然後增加一些程式碼變成如下
private Timer MyTimer;
public Service1()
{
InitializeComponent();
this.AutoLog = false;
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyLog");
}
eventLog1.Source = "MySource";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("Start Timer.");
MyTimer = new Timer();
MyTimer.Elapsed += new ElapsedEventHandler(MyTimer_Elapsed);
MyTimer.Interval = 10 * 1000;
MyTimer.Start();
}
private void MyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
eventLog1.WriteEntry("Timer Ticked.");
}
protected override void OnStop()
{
eventLog1.WriteEntry("Stop Timer.");
MyTimer.Stop();
MyTimer = null;
}
剩下就讓大家自由發揮了
------------------------------
安裝 / 解除安裝 服務
剛剛不是有提到 installutil.exe 嗎?
官方文件是寫
安裝服務的時候執行指令
InstallUtil MyService1.exe
解除安裝的時候執行指令
InstallUtil /u MyService1.exe
但事情沒有這麼簡單
installutil.exe 它其實是在
C:\Windows\Microsoft.NET\Framework\<版本號> 底下
版本號會有很多個
因為我這個專案是用.Net Framework 4.5
所以就用v4.0.30319
有安裝.Net Framework 4.5都會有這個資料夾,也會有這個程式
但還有一個問題
因為我執行時是用LocalSystem
這個需要額外的管理員權限
-------
在這裡我寫了二個Bat檔案,做安裝服務與解除安裝的服務
這裡只列安裝服務,反正把指令加上 /u 就是 解除安裝就不列出了
Install-MyService1.bat
內容為
@ECHO OFF
net session >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
ECHO ERROR: Please run Bat as Administrator.
PAUSE
EXIT /B 1
)
@SETLOCAL enableextensions
@CD /d "%~dp0"
REM The following directory is for .NET 4
SET DOTNETFX4=%SystemRoot%\Microsoft.NET\Framework\v4.0.30319
SET PATH=%PATH%;%DOTNETFX4%
ECHO Installing MyService1...
ECHO ---------------------------------------------------
InstallUtil /i .\MyService1.exe
ECHO ---------------------------------------------------
ECHO Done.
PAUSE
藍色字自行修改所需要的.Net版本號
還有服務程式的exe名稱
橘色字是檢查管理員權限用的
若Account不是選LocalSystem的話
可以刪掉它
------------------------------
執行測試
完成之後可以做安裝,然後做測試
在Install-MyService1.bat按右鍵 -> Run as administrator
打開控制台 -> 系統管理工具 -> 服務
這個列表裡面就會多了一個你的服務
裡面的名稱都跟剛剛打的一樣
那我們剛剛寫的日誌呢?
控制台 -> 系統管理工具 -> 事件檢視器
找到Applications and Services (應用程式及服務記錄檔)
就會多出一個MyLog
裡面就是我們寫的日誌檔
除錯
之前在重複若干次的 安裝服務/解除安裝服務 的時候
有遇到EventLog的問題
可以嘗試去登錄編輯器(regedit)刪除以下機碼
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\eventlog\MySource
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\MySource
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MySource
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\MySource
在執行 解除安裝服務 的程式
參考資料:
http://blog.wahahajk.com/2008/06/cservice.html
http://msdn.microsoft.com/en-us/library/y817hyb6(v=vs.110).aspx
http://gogo1119.pixnet.net/blog/post/27575780-%5Bc%23%5D-windows-service%E5%BB%BA%E7%AB%8B%E7%AF%84%E4%BE%8B
http://www.cnblogs.com/xianspace/archive/2009/04/05/1429835.html
http://stackoverflow.com/questions/3307151/receiving-has-already-been-registered-from-eventlog-createeventsource-ev
http://stackoverflow.com/questions/4824051/problem-installing-windows-service
留言列表