你的位置:首页 > ASP.net教程

[ASP.net教程]C# Windows Service服务的创建和调试


前言


  关于Windows服务创建和调试的文章在网络上的很多文章里面都有,直接拿过来贴在这里也不过仅仅是个记录,不会让人加深印象。所以本着能够更深刻了解服务项目的创建和调试过程及方法的目的,有了这篇记录。

目录


一、什么是Windows Service服务?
二、基于C#的Windows Service服务的创建、安装、卸载?
三、Windows Service服务开发过程中如何调试代码?

正文


一、什么是Windows Service服务?
  Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这使服务非常适合在服务器上使 用,或任何时候,为了不影响在同一台计算机上工作的其他用户,需要长时间运行功能时使用。还可以在不同于登录用户的特定用户帐户或默认计算机帐户的安全上 下文中运行服务。(百度百科)
 
二、基于C#的Windows Service服务的创建、安装、卸载?
  1、打开:Visual Studio 2010 => 新建 => 项目 => Windows 服务,如图:
   
  3、项目会自动生成安装文件 ProjectInstaller.cs ,并且分别设置 serviceIntaller1 与 serviceProcessInstaller1 的属性。
  
 1 using System; 2 using System.ServiceProcess; 3  4 namespace WindowsServiceTest 5 { 6   public partial class MyFirstWinService : ServiceBase 7   { 8     public MyFirstWinService() 9     {10       InitializeComponent();11     }12 13     protected override void OnStart(string[] args)14     {15       string str = "服务开启";16       TestClass.WriteMsgToFile(@"E:\MyProjects\WSExample.txt", str + ",时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));17     }18 19     protected override void OnStop()20     {21       string str = "服务停止";22       TestClass.WriteMsgToFile(@"E:\MyProjects\WSExample.txt", str + ",时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));23     }24 25     protected override void OnContinue()26     {27       string str = "服务继续运行";28       TestClass.WriteMsgToFile(@"E:\MyProjects\WSExample.txt", str + ",时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));29     }30 31     protected override void OnPause()32     {33       string str = "服务暂停";34       TestClass.WriteMsgToFile(@"E:\MyProjects\WSExample.txt", str + ",时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));35     }36   }37 38   public static class TestClass39   {40     public static void WriteMsgToFile(string fileName, string content)41     {42       using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileName, true))43       {44         sw.WriteLine(content);45       }46     }47   }48 }

View Code

 
  5、在上面的步骤中,已经完成了服务的开发工作。接下来就是服务的安装过程:
  1)安装服务的CMD命令:%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe WindowsServiceTest.exe
  2)卸载服务的CMD命令:%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u WindowsServiceTest.exe
    不过在这里我把命令操作写成两个批处理文件:
Install.bat
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe WindowsServiceTest.exeNet Start ServiceTest

Uninstall.bat
net stop ServiceTest%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u WindowsServiceTest.exe


  将批处理文件放入项目的bin->Debug文件夹下面,这样就可以方便安装和卸载服务了。当然,写成批处理文件,也方便使用程序控制服务的安装和卸载。
    这里有一个问题:就是在附加到进程的同时 OnStart 函数已经执行完毕,所以对 Onstart 无法调试。这个可以通过设置启动服务延时来加载调试。
    private System.Timers.Timer timerDelay;    protected override void OnStart(string[] args)    {      try      {        ///delay start the SynData 30seconds        timerDelay = new System.Timers.Timer(30000);          timerDelay.Elapsed += new System.Timers.ElapsedEventHandler(timerDelay_Elapsed);        timerDelay.Start();      }      catch (Exception ex)      {        this.PrintExceptions(ex);      }    }    void timerDelay_Elapsed(object sender, System.Timers.ElapsedEventArgs e)    {      timerDelay.Enabled = false;      timerDelay.Close();            //你要加的代码      string str = "服务开启";      TestClass.WriteMsgToFile(FilePath, str + ",时间:" + DateTime.Now.ToString(DateFormat));    }

View Code

  注意:正常服务的启动时间为30秒左右,当服务启动时间超过30秒会报错!,所以不要在OnStart中做过多的操作,也可以用这种延时的方法启动服务,以防在启动服务时超时。
 
方法3:修改Main函数中的起始代码
  这是一个取巧的方法,在Main函数中,注释掉原有自动生成的代码,手动实例化所写的服务类。如下代码中红色部分:
      static class Program
     {
         /// <summary>
         /// 应用程序的主入口点。
         /// </summary>
         static void Main()
         {
             //ServiceBase[] ServicesToRun;
             //ServicesToRun = new ServiceBase[]
             //{
             //    new ServiceTest()
             //};
             //ServiceBase.Run(ServicesToRun);

             ServiceTest st = new ServiceTest(); //ServiceTest为自己建的服务类
             st.OnStart();
         }
     }
  然后需要把ServiceTest类中的 protected override void OnStart(string[] args)修改为 public void OnStart(),接着就可以在OnStart()方法里面设置断点,按F5运行调试了。
        public void OnStart()
        {
            string str = "服务开启";
            TestClass.WriteMsgToFile(FilePath, str + ",时间:" + DateTime.Now.ToString(DateFormat));
            //Code Something......
        }
  ServiceTest类中的其他方法也可以这样进行调试,待调试完毕后,把方法再修改回原来的样子既可。
 
一点补充:
1)Service启动属性:
    Manual      服务安装后,必须手动启动。
    Automatic    每次计算机重新启动时,服务都会自动启动。
    Disabled     服务无法启动。
 
2)新建的Service项目,其中各属性的含义(服务类 MyFirstWinService.cs 设计视图->右键属性):
    Autolog   是否自动写入系统的日志文件
    CanHandlePowerEvent   服务时候接受电源事件
    CanPauseAndContinue   服务是否接受暂停或继续运行的请求
    CanShutdown   服务是否在运行它的计算机关闭时收到通知,以便能够调用 OnShutDown 过程
    CanStop   服务是否接受停止运行的请求
    ServiceName   服务名
 
3) 也可以在系统服务管理器中,设置相应Service的属性或启动方式等 
    计算机管理 -> 服务和应用程序  -> 服务  -> ...


 
 
  这些只是我目前知道的调试方法,当然肯定还有,有时候还需要多种方法结合着来调试。