- Windows Service簡介:
一個Windows服務程序是在Windows操作系統下能完成特定功能的可執行的應用程序。Windows服務程序雖然是可執行的,但是它不像一般的可執行文件通過雙擊就能開始運行了,它必須有特定的啟動方式。這些啟動方式包括了自動啟動和手動啟動兩種。對於自動啟動的Windows服務程序,它們在Windows啟動或是重啟之后用戶登錄之前就開始執行了。只要你將相應的Windows服務程序注冊到服務控制管理器(Service Control Manager)中,並將其啟動類別設為自動啟動就行了。而對於手動啟動的Windows服務程序,你可以通過命令行工具的NET START 命令來啟動它,或是通過控制面板中管理工具下的服務一項來啟動相應的Windows服務程序。
同樣,一個Windows服務程序也不能像一般的應用程序那樣被終止。因為Windows服務程序一般是沒有用戶界面的,所以你也要通過命令行工具或是下面圖中的工具來停止它,或是在系統關閉時使得Windows服務程序自動停止。因為Windows服務程序沒有用戶界面,所以基於用戶界面的API函數對其是沒有多大的意義。為了能使一個Windows服務程序能夠正常並有效的在系統環境下工作,程序員必須實現一系列的方法來完成其服務功能。Windows服務程序的應用范圍很廣,典型的Windows服務程序包含了硬件控制、應用程序監視、系統級應用、診斷、報告、Web和文件系統服務等功能。
和Windows服務程序相關的命名空間涉及到以下兩個:System.ServiceProcess 和System.Diagnostics。
實際編寫方式,我就不寫了,大家可以看下petercao的博文:http://www.cnblogs.com/bluestorm/p/3510398.html
- 代碼結構
-
ListenService :windows 服務的主體,實現了windows 服務代碼、服務安裝及卸載
- ListenServiceUI: 我做了一個簡易的登陸窗口,和服務操作界面,大家就不需要去services.msc 服務管理器 操作啟動關閉服務了
ListenService 中,DataMonitorService類是服務類,里面包含了服務的啟動和停止,還有一個定時器,執行windows服務的定時操作
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading; using Common; namespace ListenService { partial class DataMonitorService : ServiceBase { public DataMonitorService() { InitializeComponent(); } private ListenDataClass sdc = new ListenDataClass(); System.Timers.Timer timer1;//計時器 protected override void OnStart(string[] args) { // 記錄服務啟動日志。 LogTextHelper.Log("服務啟動前准備."); LogTextHelper.Log("服務已經啟動,啟動時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ")); //線程 檢查定時器 if (timer1 == null) { LogTextHelper.Log("定時器null,開始初始化定時器"); timer1 = new System.Timers.Timer(); //設置定時間隔時間,默認60秒, int SecondCount = 60; //獲取配置文件中的間隔時間,如果有將替換默認 string sc = System.Configuration.ConfigurationManager.AppSettings["syncSecond"]; if (!string.IsNullOrEmpty(sc) && ValidateUtil.IsNumber(sc)) { //將獲取配置文件的定時間隔 記錄下來 <add key="syncSecond" value="60"/> SecondCount = Convert.ToInt32(sc); } //1000毫秒=1秒,與定時間隔 相乘,計算共多少毫秒 timer1.Interval = 1000 * SecondCount; //綁定監聽事件 timer1.Elapsed += new System.Timers.ElapsedEventHandler(sdc.SynData); //啟動定時器 timer1.Enabled = true; LogTextHelper.Log("定時器初始化完成,定時器已經啟動。"); } else { timer1.Enabled = true; LogTextHelper.Log("定時器初始化完成,定時器已經啟動。"); } } protected override void OnStop() { //當服務結束時,結束定時器 if (timer1 != null) timer1.Enabled = false; // TODO: 在此處添加代碼以執行停止服務所需的關閉操作。 LogTextHelper.Log("服務已經結束,結束時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ")); } } }
Install.bat 和Uninstall.bat 兩個文件,分別是安裝服務和卸載服務,這兩個文件不需要我們手動操作,將在UI界面的程序中自動調用。
ListenServiceUI,里面分別有2個頁面,一個是登陸,一個是操作
登陸界面
服務控制窗口
登陸名:admin,密碼123456,程序中寫死了,如果大家願意,可以寫入文件或數據庫,我的例子,簡單的一些更容易操作。
控制窗口可以安裝、啟動、停止和卸載服務。點Exit時,僅僅是關閉了ui,不會對程序進行處理。
后台管理代碼如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.ServiceProcess; using System.IO; namespace ListenServiceUI { public partial class ServiceSetting : Form { public ServiceSetting() { InitializeComponent(); } //安裝服務 private void btnInstallService_Click(object sender, EventArgs e) { ; ShowState("開始安裝服務"); try { string CurrentDirectory = System.Environment.CurrentDirectory; System.Environment.CurrentDirectory = CurrentDirectory + "\\Service"; ShowState("查找服務目錄"); Process process = new Process(); process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = "Install.bat"; process.StartInfo.CreateNoWindow = true; process.Start(); System.Environment.CurrentDirectory = CurrentDirectory; ShowState("服務安裝完成。"); } catch (Exception ex) { string msg = ex.Message; if (ex.InnerException != null) msg += ex.InnerException.Message; ShowState("安裝服務出現錯誤:" + msg); } } //卸載 private void btnUninstallService_Click(object sender, EventArgs e) { ShowState("開始卸載服務"); try { string CurrentDirectory = System.Environment.CurrentDirectory; System.Environment.CurrentDirectory = CurrentDirectory + "\\Service"; Process process = new Process(); process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = "Uninstall.bat"; process.StartInfo.CreateNoWindow = true; process.Start(); System.Environment.CurrentDirectory = CurrentDirectory; ShowState("服務卸載完成。"); } catch (Exception ex) { string msg = ex.Message; if (ex.InnerException != null) msg += ex.InnerException.Message; ShowState("卸載服務出現錯誤:" + msg); } } //啟動 private void btnStartService_Click(object sender, EventArgs e) { try { ShowState("啟動服務開始"); ServiceController serviceController = new ServiceController("DataMonitorService"); serviceController.Start(); ShowState("啟動服務完成。"); } catch (Exception ex) { string msg = ex.Message; if (ex.InnerException != null) msg += ex.InnerException.Message; ShowState("啟動服務出現錯誤:" + msg); } } //停止 private void btnStopService_Click(object sender, EventArgs e) { try { ShowState("停止服務開始"); ServiceController serviceController = new ServiceController("DataMonitorService"); if (serviceController.CanStop) serviceController.Stop(); ShowState("停止服務完成。"); } catch (Exception ex) { string msg = ex.Message; if (ex.InnerException != null) msg += ex.InnerException.Message; ShowState("停止服務出現錯誤:" + msg); } } //查看狀態 private void btnShowState_Click(object sender, EventArgs e) { try { ServiceController serviceController = new ServiceController("DataMonitorService"); string Status = serviceController.Status.ToString(); ShowState("當前服務狀態是:" + Status); } catch (Exception ex) { ShowState("查看狀態出現錯誤:" + ex.Message); } } private void ShowState(string message) { textBox1.Text = message; } private void ServiceSetting_Load(object sender, EventArgs e) { string Installbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe {0} Net Start DataMonitorService sc config DataMonitorService start = auto"; string directory = Path.Combine(System.Environment.CurrentDirectory, "Service"); File.WriteAllText(Path .Combine(directory, "Install.bat"), string.Format(Installbat_content, Path.Combine(directory, "ListenService.exe"))); string Unistallbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u {0}"; File.WriteAllText(Path.Combine(directory, "Uninstall.bat"), string.Format(Unistallbat_content, Path.Combine(directory, "ListenService.exe"))); this.Hide(); Login login = new Login(); if (login.ShowDialog() == DialogResult.OK) { myConfig.loginstate = 1; this.Show(); ShowState("一切運行正常。"); } else { this.Width = 1; this.Height = 1; this.StartPosition = FormStartPosition.CenterScreen; Application.Exit(); return; } } private void btnExitApp_Click(object sender, EventArgs e) { Application.Exit(); } } }
在使用UI時要注意的2個事項
1、啟動ui時,必須使用管理員身份登陸,不然是沒有權限對服務進行操作的
2、安裝服務和卸載服務的bat批處理文件中,要寫服務的絕對路徑,如果寫相對路徑偶爾會出現問題。我這里在ServiceSetting.cs類中,通過程序進行了服務位置定位。
string Installbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe {0} Net Start DataMonitorService sc config DataMonitorService start = auto"; string directory = Path.Combine(System.Environment.CurrentDirectory, "Service"); File.WriteAllText(Path .Combine(directory, "Install.bat"), string.Format(Installbat_content, Path.Combine(directory, "ListenService.exe"))); string Unistallbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u {0}"; File.WriteAllText(Path.Combine(directory, "Uninstall.bat"), string.Format(Unistallbat_content, Path.Combine(directory, "ListenService.exe")));
配置文件中設定定時器 操作間隔
為了方便修改,將定時間隔放在了app.config中,
<!--同步間隔,單位:秒--> <add key="syncSecond" value="60"/>
啟動后效果:
登陸
操作界面
安裝服務后
服務管理器中的服務(如果需要隨機啟動,請將手動設置為自動)
設置自動啟動
代碼下載地址:http://download.csdn.net/detail/l9861125/9594564