Visual C#中,如何建立、調用Windows服務?

來源:互聯網
上載者:User
  Windows服務是獨立於登入使用者而工作的Windows應用程式,它通常在電腦啟動時開始執行,且常常連續執行,直到電腦關閉為止。像Exchange Server,IIS和殺毒軟體等都使用這種方式,這樣就可以獨立於某一使用者而且可以在任何使用者登入前來運行,同時也可以服務於所有的進程,從而以一種服務的形式存在。
  
  正因為Windows服務有著這麼多的特性,因此,當需要一些特殊功能的時候就可以考慮使用Windows服務來解決問題。比如下面我們要做的這個例子。對於我們這些程式設計人員,電腦是在一起工作時間最長的夥伴,每天都會對著它的螢幕八個小時以上,還不包括下班後在家打遊戲的時間,因此,保護眼睛是最重要的了。問題的起因來源於本人周六去眼科對雷射手術的複查,大夫一再向我強調眼睛的自我調節能力,就是說只要你能保證你每隔一個小時左右就閉眼休息或向遠處眺望,離開電腦螢幕,那麼已經治好的近視就不會反彈。本人雖是自律性比較強的人,但在電腦螢幕面前就不再如此了,往往幾個小時也不抬頭一次,為了眼睛的健康,我決定把這個艱巨的任務交由電腦來完成,讓它在一小時左右自動提醒我休息五分鐘。如此一來,豈不是再也不用顧慮這件事了。
  
  功能雖然簡單,但要寫個程式放在啟動組裡每天自動運行也不是一個好的辦法,正巧以前也沒做過Windows服務,不如索性來試一試,同進也看看.NET為我們提供了多麼先進的功能吧,於是決定,就用C#來做一個提醒我保護眼睛的Windows服務,取名就叫CareEye吧。
  
  運行Visual Studio.NET 2003,建立一個C#的Windows服務項目,在CareEye.cs的設計檢視提示可以把需要的控制項和組件拖動到這上面,假如想要做系統日誌的話當然就可以把EventLog組件拖過來了,不過這個程式好像不需要這些東西,還是算了吧。那麼計時要不要採用計時器控制項呢?想了一下,這個控制項雖然好用,但太常用了,本著學習新知識的原則,最恰當的恐怕就是線程了,而且在以後做其他Windows服務的時候線程肯定是必需的,所以還是用線程好,這樣我只要線上程中完成對時間的監測,把線程的啟動和停止交給服務的啟動和停止,呵,很方便啊。
  
  再來看CareEye.cs的來源程式,一大堆沒見過的東西,不過仔細分析一下也就沒什麼了。CareEye類派生於ServiceBase類,因此繼承了基本服務類的特性,顯然Main()方法會由SCM(服務控制管理程式)調用,在這個方法中Run一個新的CareEye執行個體,這樣就運行了一個Windows服務,OnStart()和OnStop()明顯是用於啟動和停止服務的響應函數了。
  
  注意在Main()方法中有一個ServiceBase[]的數組,它是為那些一個服務進程包含多個服務準備的,對於這個程式來說,它只有一個CareEye服務,因此完全可以把這個數組刪除,而只是使用System.ServiceProcess.ServiceBase.Run(new CareEye());一句就夠了。
  
  接下來為了使用線程,需要引入System.Threading命名空間,為了使用對話方塊,還需要引入System.Windows.Forms命名空間,這是為了將來提示使用者時顯示對話方塊而準備的。
  
  下面為類CareEye添加一個成員欄位private Thread MainThread;同時在建構函式中對其進行初始化:
  
  MainThread=new Thread(new ThreadStart(ThreadFunc));
  MainThread.Priority=ThreadPriority.Lowest;
  
  這裡把線程的優先順序設到最低,這樣不會耗用過多的系統效能。這個線程對象使用ThreadFunc作為線程函數,因此將這個線程函數補充完整:
  
  public static void ThreadFunc()
  {
  int LastHour=DateTime.Now.Hour;
  while (true)
  {
  System.Threading.Thread.Sleep(60000);
  if (DateTime.Now.Hour-1==LastHour)
  {
  MessageBox.Show("為了愛護您的眼睛,請您暫時休息5分鐘並向遠處眺望!","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1,
  MessageBoxOptions.DefaultDesktopOnly);
  LastHour=DateTime.Now.Hour;
  }
  }
  }
  
  餘下的代碼就簡單了,只要在OnStart中啟動線程,在OnStop中停止線程就行了。
  
  以上的服務程式雖然很簡單,線程的處理上也不很恰當,也違背了很多服務程式的原則比如介面顯示等,但對於本人的需求而言是足夠了,因此就如此製作了。如果你有需要,當然可以把對話方塊改為其他的提醒方式如響鈴等,線程也可以使用核心對象同時使用更好的處理方法。
  
  Windows服務就做完了,餘下的就是要測試了,但發現這個EXE無法運行,它會提示你該EXE需要使用安裝程式來安裝服務,看來不可能寫一個程式就算是Windows服務了,還要把它註冊到Windows才行。
  
 在這,項目中,添加一個新項《安裝程式類》,Installer2.cs ,接著在工具箱中,添加二個組件:serviceInstaller 和 serviceProcessInstaller 並相應的修改與選擇二者的屬性。

  接下來,右擊CareEye.cs的設計檢視,添加安裝程式,(VS.NET想得就是挺周到的),這下又出來一批代碼,不過好在不用改代碼了,只要把Account的賬戶類型設成LocalSystem,把StartType設成手動啟動就行了,這裡用手動是為了方便調試,以後可以改成自動類型。
  
  編譯完後,還是無法運行,此處還需要一步,就是運行installutil來安裝這個服務,其安裝和卸載的用法為:
  
//C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe  或用vs命令控制台
  installutil CareEye.exe
  installutil /u CareEye.exe
  
  安裝完後能過系統的服務管理員你就可以看到你的服務了,只要點擊啟動就可以把它啟動,把時間向前改一個小時它就會提醒你需要休息了,呵呵,夠簡單了吧。
  
  如果你想製作成安裝包分發給自己的朋友,只需要再添加個部署項目就行了,不過為了完成自註冊,要在自訂動作編輯器中的安裝階段添加一個自訂的安裝操作,把InstallerClass屬性設成TRUE即可。
  
  以下是careeye.cs的來源程式:
  
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.Data;
  using System.Diagnostics;
  using System.ServiceProcess;
  using System.Threading;
  using System.Windows.Forms;
  namespace CareEye
  {
  public class CareEye : System.ServiceProcess.ServiceBase
  {
  private Thread MainThread;
  /// <summary>
  /// 必需的設計器變數。
  /// </summary>
  private System.ComponentModel.Container components = null;
  
  public CareEye()
  {
  // 該調用是 Windows.Forms 組件設計器所必需的。
  InitializeComponent();
  
  // TODO: 在 InitComponent 調用後添加任何初始化
  MainThread=new Thread(new ThreadStart(ThreadFunc));
  MainThread.Priority=ThreadPriority.Lowest;
  }
  
  // 進程的主進入點
  static void Main()
  {
  //System.ServiceProcess.ServiceBase[] ServicesToRun;
  
  // 同一進程中可以運行多個使用者服務。若要將
  //另一個服務添加到此進程,請更改下行
  // 以建立另一個服務物件。例如,
  //
  // ServicesToRun = New System.ServiceProcess.ServiceBase[] {new CareEye(), new MySecondUserService()};
  //
  //ServicesToRun = new System.ServiceProcess.ServiceBase[] { new CareEye() };
  
  System.ServiceProcess.ServiceBase.Run(new CareEye());
  }
  
  /// <summary>
  /// 設計器支援所需的方法 - 不要使用代碼編輯器
  /// 修改此方法的內容。
  /// </summary>
  private void InitializeComponent()
  {
  //
  // CareEye
  //
  this.ServiceName = "CareEye";
  
  }
  
  /// <summary>
  /// 清理所有正在使用的資源。
  /// </summary>
  
  protected override void Dispose( bool disposing )
  {
  if( disposing )
  {
  if (components != null)
  {
  components.Dispose();
  }
  }
  base.Dispose( disposing );
  }
  
  /// <summary>
  /// 設定具體的操作,以便服務可以執行它的工作。
  /// </summary>
  protected override void OnStart(string[] args)
  {
  // TODO: 在此處添加代碼以啟動服務。
  MainThread.Start();
  }
  
  /// <summary>
  /// 停止此服務。
  /// </summary>
  protected override void OnStop()
  {
  // TODO: 在此處添加代碼以執行停止服務所需的關閉操作。
  MainThread.Abort();
  }
  public static void ThreadFunc()
  {
  int LastHour=DateTime.Now.Hour;
  while (true)
  {
  System.Threading.Thread.Sleep(60000);
  if (DateTime.Now.Hour-1==LastHour)
  {
  MessageBox.Show("為了愛護您的眼睛,請您暫時休息5分鐘並向遠處眺望!","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly);
  LastHour=DateTime.Now.Hour;
  }
  }
  }
  }
  }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.