Windows服务创建及安装

来源:互联网 发布:划船机选购知乎 编辑:程序博客网 时间:2024/06/05 06:38

     如何创建一个作为Windows服务的应用程序。内容包含什么是Windows服务,如何创建、安装和调试它们。会用到System.ServiceProcess.ServiceBase命名空间的类。

什么是Windows服务?
   Windows服务应用程序是一种需要长期运行的应用程序,它对于服务器环境特别适合。它没有用户界面,并且也不会产生任何可视输出。任何用户消息都会被写进Windows事件日志。计算机启动时,服务会自动开始运行。它们不要用户一定登录才运行,它们能在包括这个系统内的任何用户环境下运行。通过服务控制管理器,Windows服务是可控的,可以终止、暂停及当需要时启动。

   Windows 服务,以前的NT服务,都是被作为Windows NT操作系统的一部分引进来的。它们在Windows 9x及Windows Me下没有。你需要使用NT级别的操作系统来运行Windows服务,诸如:Windows NT、Windows 2003 Professional或Windows 2003 Server。举例而言,以Windows服务形式的产品有:Microsoft Exchange、SQL Server,还有别的如设置计算机时钟的Windows Time服务。
创建一个Windows服务

  我们即将创建的这个服务除了演示什么也不做。服务被启动时会把一个条目信息登记到一个数据库当中来指明这个服务已经启动了。在服务运行期间,它会在指定的时间间隔内定期创建一个数据库项目记录。服务停止时会创建最后一条数据库记录。这个服务会自动向Windows应用程序日志当中登记下它成功启动或停止时的记录。

  Visual Studio .NET能够使创建一个Windows服务变成相当简单的一件事情。启动我们的演示服务程序的说明概述如下。

Windows服务的构成

  在你类后面所包含的代码里,你会注意到你所创建的Windows服务扩充了System.ServiceProcess.Service类。所有以.NET方式建立的Windows服务必须扩充这个类。它会要求你的服务重载下面的方法,Visual Studio默认时包括了这些方法。

• Dispose – 清除任何受控和不受控资源(managed and unmanaged resources)
• OnStart – 控制服务启动
• OnStop – 控制服务停止

Windows服务样例

下面是一个测试案例,服务名为HelloWorldService黑色部分为自动生成,红色部分为我加进去的代码,绿色为我加入的注释,此案例没有其他意义,只是将记录插入到数据库中。

选择Visual C#->Windows->Windows 服务,创建一个HelloWorldService项目。


通过ServiceName更改服务的名称为”HelloWorldService“,这是最后在安装服务成功后在服务管理面板出现的名称。



 

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Configuration.Install;
using SysData.Db;

namespace serverTest
{
 public class HelloWorldService : System.ServiceProcess.ServiceBase
 {
  private System.Timers.Timer timer1;
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;

  public Service1()
  {
   // 该调用是 Windows.Forms 组件设计器所必需的。
   InitializeComponent();

   // TODO: 在 InitComponent 调用后添加任何初始化
  }

  // 进程的主入口点
  static void Main()
  {
   System.ServiceProcess.ServiceBase[] ServicesToRun;
 
   // 同一进程中可以运行多个用户服务。若要将
   //另一个服务添加到此进程,请更改下行
   // 以创建另一个服务对象。例如,
   //
   //   ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
   //
   ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };

   System.ServiceProcess.ServiceBase.Run(ServicesToRun);
  }

  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器
  /// 修改此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   this.timer1 = new System.Timers.Timer();
   ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
   //
   // timer1
   //
   this.timer1.Enabled = true;
   this.timer1.Interval = 30000;
   this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
   //
   // HelloWorldService
   //
   this.ServiceName = "HelloWorldService";
   ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

  }

  /// <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: 在此处添加代码以启动服务。
   this.timer1.Enabled = true;
   this.LogMessage("Service Started");

  }
 
  /// <summary>
  /// 停止此服务。
  /// </summary>
  protected override void OnStop()
  {
   // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
   this.timer1.Enabled = false;
   this.LogMessage("Service Stopped");

  }

  private void LogMessage(string xMsg)
  {
   try
   {
      //这里向数据库中插入一条信息为 xMsg的记录,下边是我调用事先写好的Db类添加记录的方法,您也可以使用其他办法来写入数据库。
    //Db.QuerySQL("Insert into SysMsg (SysMsg) values ('"+xMsg+"')");
   }
   catch
   {
    //不做任何操作
   }
  }

  private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
   LogMessage("检查服务运行!");
  }
 }
}

设计界面点右键,在弹出菜单中选择”添加安装程序“。 


点击后出来的设计界面上添加了两个控件——ServiceProcessInstall和ServiceInstaller。



 

ServiceProcessInstall安装一个可执行文件,该文件包含扩展 ServiceBase 的类。该类由安装实用工具(如 InstallUtil.exe)在安装服务应用程序时调用。在这里主要是修改其Account属性。ServiceAccount指定服务的安全上下文,安全上下文定义其登录类型。


LocalService    充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器。
LocalSystem    服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机。
NetworkService    提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器。
User    由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值。

ServiceInstaller安装一个类,该类扩展 ServiceBase 来实现服务。在安装服务应用程序时由安装实用工具调用该类。在这里主要修改其StartType属性。此值指定了服务的启动模式。

Automatic 指示服务在系统启动时将由(或已由)操作系统启动。如果某个自动启动的服务依赖于某个手动启动的服务,则手动启动的服务也会在系统启动时自动启动。
Disabled 指示禁用该服务,以便它无法由用户或应用程序启动。
Manual 指示服务只由用户(使用“服务控制管理器”)或应用程序手动启动。

5、上面这些都是安装包最终要安装/卸载的对象。下面就来看看如何用.net制作安装包。
需要在解决方案里边添加一个安装项目,取其名称为HelloWorldSetup。


添加工程后,在默认的视图界面右键点击”应用程序文件夹“,选择”添加“->”项目输出“。

在弹出的窗口中选择”主输出“,点击”确定“。


上面的步骤定义了最后在应用程序文件夹中包含的内容。下面来定义其他方面的内容。在项目上点右键,选择 视图->自定义操作。



出来如下的界面,然后在”自定义操作“上点右键,选择”添加自定义操作“。


在弹出的窗口中双击”应用程序文件夹“。


然后选择”主输出来自HelloWorldService(活动)“,点击”确定“。


选择之后会发现所有的操作下边都添加了刚才选定的项。做到这一步,就能使安装程序卸载时不仅把程序卸载下来,也能把服务卸载下来。


接下来在安装项目上点右键,选择”生成“,就能使安装程序正常发布了,成功后会生成两个文件。


安装Windows服务

  Windows服务不同于普通Windows应用程序。不可能简简单单地通过运行一个EXE就启动Windows服务了。安装一个Windows服务应该通过使用.NET Framework提供的InstallUtil.exe来完成,或者通过诸如一个Microsoft Installer (MSI)这样的文件部署项目完成。


添加服务安装程序

  创建一个Windows服务,仅用InstallUtil程序去安装这个服务是不够的。你必须还要把一个服务安装程序添加到你的Windows服务当中,这样便于InstallUtil或是任何别的安装程序知道应用你服务的是怎样的配置设置。

执行命令“InstallUtil.exe Service.exe”注册这个服务,使它建立一个合适的注册项。
注意:直接运行 InstallUtil.exe 可能会失败,提示:
'InstallUtil.exe' 不是内部或外部命令,也不是可运行的程序或批处理文件。
您可以在C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727 找到这个可执行程序

  在每次需要修改Windows服务时,这就会要求你卸载和重新安装这个服务。不过要注意在卸载这个服务前,最好确保服务管理控制台已经关闭,这会是一个很好的习惯。如果没有这样操作的话,你可能在卸载和重安装Windows服务时会遇到麻烦。仅卸载服务的话,可以执行相的InstallUtil命令用于注销服务,不过要在后面加一个/u命令开关。

参考:http://comdeng.com/blog/article/10065.html
 

原创粉丝点击