close
文章出處

有很多時候,我們需要創建Windows Service。 這篇文章可以算是一個入門指南吧,希望對初學者有幫助.

 

要創建Windows Service, 首先選擇Windows服務項目,如下圖:

image

這里我想創建一個Windows服務,定時的執行一些任務。

public partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }

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

    protected override void OnStop()
    {
    }
}

OnStart :服務啟動的時候執行,

OnStop:服務停止的時候執行

 

為了定時的執行任務,我修改代碼如下:

namespace TimeWindowsService
{
    public partial class Service1 : ServiceBase
    {
        System.Timers.Timer timer = null;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            timer = new System.Timers.Timer();
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 1000;
            timer.Start();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("Time elapsed");
        }

        protected override void OnStop()
        {
            if (timer != null)
            {
                timer.Stop();
            }
        }
    }
}

 

按F5運行代碼,會提示:

image

這代表我們必須先使用Installutil.exe 來安裝服務。

當然你可以打開命令行,然后輸入命令來安裝服務,不過在這里我打算使用外部工具來執行InstallUtil.exe。

image

其中命令是:C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe

點擊確定,可以發現一個InstallService 命令。

image

點擊InstallService,可以發現屏幕閃了一下,然后又過了,很明顯是因為我們的命令出錯了。

注意,我們在添加InstallService的時候,選擇的是image,所以即使有錯誤信息,也會一閃而過。

修改InstallService的命令如下:

image

再次運行InstallService,可以看到:

image

這代表InstallService 的時候出錯了,找不到文件,我們希望它找的是TimeWindowsService.exe,

而不是\bin\debug\TimeWindowsService

所以正確的設置InstallService命令應該是下面這樣:

image

保存,然后運行,結果如下:

image

還是沒有安裝成功,因為沒有安裝程序。

有很多教程會告訴你,需要添加一個像下面這樣的類:http://www.cnblogs.com/jjstar/articles/20353.aspx

using System.Collections;
using System.Configuration.Install;
using System.ServiceProcess;
using System.ComponentModel;

namespace WindowsService1
{
 /// <summary>
 /// myInstall 的摘要說明。
 /// </summary>
 /// 
 [RunInstaller(true)]
 public class myInstall : Installer 
 {

  private ServiceInstaller serviceInstaller;
  private ServiceProcessInstaller processInstaller;
  public myInstall()
  {
   processInstaller = new ServiceProcessInstaller();
   serviceInstaller = new ServiceInstaller();

   processInstaller.Account = ServiceAccount.LocalSystem;
   serviceInstaller.StartType = ServiceStartMode.Automatic;
   serviceInstaller.ServiceName = "WindowsService1";

   Installers.Add(serviceInstaller);
   Installers.Add(processInstaller);
  }
 }
}

對于記性不好的人來說,很容易問的一個問題是:VS有提供相關的快捷鍵嗎?,當然,VS提供了。

在Service1.cs 設計頁面點擊,添加安裝程序,vs 就會自動幫你生成一個Installer 的類。

image

 

添加的類是:

image

serviceProcessInstaller1 :

安裝一個可執行文件,該文件包含擴展 System.ServiceProcess.ServiceBase 的類。 該類由安裝實用工具(如 InstallUtil.exe)在安裝服務應用程序時調用。

serviceInstall1:

安裝一個類,該類擴展 System.ServiceProcess.ServiceBase 來實現服務。 在安裝服務應用程序時由安裝實用工具調用該類。

細心的讀者看看他們的屬性就知道區別在哪里了。

 

為了簡單,將account 設置為LocalSystem.

image

好了,安裝程序已經弄完了,接著上面的InstallService 吧,注意要編譯程序啊。

image

可以看到已經成功的安裝服務了。

從任務管理器中,你也可以看到安裝的服務:

image

 

OK,接著按F5 調試吧,可是:

依然出現了這個提示框,很顯然,我們不能按F5 來調試windows服務

image

 

有很多文章講述了如何調試windows服務。

1:比如這篇文章:http://www.cnblogs.com/downmoon/archive/2009/09/16/1567643.html,所采用的AttachProcess 方法。

可是有時候,由于各種各樣的原因,服務無法啟動,或者是服務由于某些原因而自動停止,所以也就不太容易附加到進程去調試了。

 

2:還有一些修改代碼的方法,比如:

添加一個DebugOnStart 的方法

public void DebugOnStart()
        {
            this.OnStart(null);
        }

        protected override void OnStart(string[] args)
        {
            timer = new System.Timers.Timer();
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 1000;
            timer.Start();
        }

然后修改main函數如下:

static void Main()
        {
            //ServiceBase[] ServicesToRun;
            //ServicesToRun = new ServiceBase[] 
            //{ 
            //    new Service1() 
            //};
            //ServiceBase.Run(ServicesToRun);

            new Service1().DebugOnStart();
        }

效果如下:

image

 

3:在構造函數中用Thread.Sleep. 然后快速的附加到進程。

image

這樣,服務就會需要10秒才能啟動,有10秒的時間,肯定可以”附加到進程”的吧

image

 

我個人比較喜歡的一種方式:

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (!Debugger.IsAttached)
            {
                Debugger.Launch();
            }

            Console.WriteLine("Time elapsed");
        }

這樣在啟動Service的時候,會提示:

image

 

點擊確定后:

image

 

這種方式是,你可以在任何時間,任何需要調試的地方添加上面的語句。

具體的可以參考Debugger 類。

 

參考的文章:http://www.codeproject.com/Articles/19914/How-to-debug-a-Windows-Service-and-not-die-in-the


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()