Windows服务应用程序

  • 一、Windows服务应用程序简介
  • 二、创建Windows服务应用程序
    • 2.1 基于ServiceBase创建服务
      • 2.1.1 使用Visual Studio中的Windows服务模板新建项目
        • 2.1.1.1 文件结构
        • 2.1.1.2 项目结构
      • 2.1.2 添加自定义事件日志功能
        • 2.1.2.1 添加EventLog组件
        • 2.1.2.2 初始化EventLog对象
        • 2.1.2.3 写入事件日志
      • 2.1.3 添加安装程序
        • 2.1.3.1 ProjectInstaller.cs
        • 2.1.3.2 ProjectInstaller.Designer.cs
        • 2.1.3.3 ServiceProcessInstaller
        • 2.1.3.4 ServiceInstaller
      • 2.1.4 安装和卸载服务
        • 2.1.4.1 安装服务
        • 2.1.4.2 卸载服务
      • 2.1.5 调试服务
        • 2.1.5.1 调试符号与pdb文件
        • 2.1.5.2 方式一:附加到服务进程
        • 2.1.5.3 方式二:修改应用程序输出类型
    • 2.2 基于TopShelf创建服务
      • 2.2.1 TopShelf
      • 2.2.2 配置TopShelf
      • 2.2.3 安装和卸载TopShelf服务
        • 2.2.3.1 安装服务
        • 2.2.3.2 卸载服务
    • 2.3 ServiceController
    • 2.4 定时服务

一、Windows服务应用程序简介

  • Windows服务应用程序

    • 在自己的Windows会话中长期运行的可执行应用程序
  • Windows服务的特点
    • 可以随Windows启动而启动

      • 不需要像控制台应用程序一样每次手动点击启动
    • 可以长期在后台执行
      • 不需要交互界面
      • 不需要担心将交互界面关闭后程序也随之关闭
    • 需要先安装在windows上才能启动应用程序
      • 不能直接启动

二、创建Windows服务应用程序

2.1 基于ServiceBase创建服务

2.1.1 使用Visual Studio中的Windows服务模板新建项目

2.1.1.1 文件结构

  • Program.cs
namespace WindowsService1
{static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>static void Main(){ServiceBase[] ServicesToRun;ServicesToRun = new ServiceBase[]{//Service1继承自ServiceBasenew Service1()};ServiceBase.Run(ServicesToRun);}}
}
  • Service1.cs

    • 继承自ServiceBase
    • 包含构造函数、启动、停止
    • 分部类
namespace WindowsService1
{public partial class Service1 : ServiceBase{public Service1(){InitializeComponent();}protected override void OnStart(string[] args){//do some business...}protected override void OnStop(){}}
}
  • Service1.Designer.cs

    • 组件设计器自动生成的代码
    • 类的文件名为Service1.Designer.cs,但类名为Service1,且为分部类
namespace WindowsService1
{partial class Service1{/// <summary> /// 必需的设计器变量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的资源。/// </summary>/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region 组件设计器生成的代码/// <summary> /// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){// // Service1// this.ServiceName = "Service1";}#endregion}
}

2.1.1.2 项目结构

  • Service1.cs

    • 包含设计和代码视图,类似WinForms

      • 双击打开设计视图
      • 在视图中双击或右键空白位置或者点击链接可跳转至代码视图
    • 属性对应于Service1.Designer.cs中的InitializeComponent()的设置
      • 可通过属性对服务进行重命名

2.1.2 添加自定义事件日志功能

2.1.2.1 添加EventLog组件

  • Visual Studio会自动在Service1.Designer.cs中添加创建EventLog对象的代码
partial class Service1
{private void InitializeComponent(){this.eventLog1 = new System.Diagnostics.EventLog();((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();// // Service1// this.ServiceName = "Service1";((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();}private System.Diagnostics.EventLog eventLog1;
}

2.1.2.2 初始化EventLog对象

public partial class Service1 : ServiceBase
{public Service1(){InitializeComponent();if (!System.Diagnostics.EventLog.SourceExists("MySource")){System.Diagnostics.EventLog.CreateEventSource("MySource","MyNewLog");}eventLog1.Source = "MySource";eventLog1.Log = "MyNewLog";}
}

2.1.2.3 写入事件日志

public partial class Service1 : ServiceBase
{...protected override void OnStart(string[] args){eventLog1.WriteEntry("In OnStart.");}
}

2.1.3 添加安装程序

2.1.3.1 ProjectInstaller.cs

  • Visual Studio自动生成ProjectInstaller.cs

    • 该类继承自System.Configuration.Install.Installer
    • 自动创建ServiceProcessInstaller和ServiceInstaller的对象
      • ServiceProcessInstaller
      • ServiceInstaller

  • ProjectInstaller.cs
namespace WindowsService1
{[RunInstaller(true)]public partial class ProjectInstaller : System.Configuration.Install.Installer{public ProjectInstaller(){InitializeComponent();}}
}

2.1.3.2 ProjectInstaller.Designer.cs

  • ProjectInstaller.Designer.cs
namespace WindowsService1
{partial class ProjectInstaller{#region 组件设计器生成的代码/// <summary>/// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();// // serviceProcessInstaller1// this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;this.serviceProcessInstaller1.Password = null;this.serviceProcessInstaller1.Username = null;// // serviceInstaller1// this.serviceInstaller1.Description = "这是描述";this.serviceInstaller1.DisplayName = "这是displayname";this.serviceInstaller1.ServiceName = "Service1";this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;// // ProjectInstaller// this.Installers.AddRange(new System.Configuration.Install.Installer[] {this.serviceProcessInstaller1,this.serviceInstaller1});}#endregionprivate System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;private System.ServiceProcess.ServiceInstaller serviceInstaller1;}
}

2.1.3.3 ServiceProcessInstaller

  • ServiceProcessInstaller

    • 由安装实用程序(例如InstallUtil.exe)调用

      • 一个服务可执行文件可能包含两个服务

        • “ Hello-World Service 1”
        • “ Hello-World Service 2”
      • 一个可执行文件创建一个ServiceProcessInstaller对象
  • ServiceProcessInstaller设置
    • Account

2.1.3.4 ServiceInstaller

  • ServiceInstaller

    • 由安装实用程序(例如InstallUtil.exe)调用
    • 一个服务创建一个ServiceInstaller对象
  • ServiceInstaller设置

2.1.4 安装和卸载服务

  • 以管理员身份打开VS的开发人员命令提示符
  • 将路径导航到服务应用程序所在文件夹
  • 利用installUtil.exe实用工具对服务进行安装和卸载
    • 该工具与.NET Framework一起安装到文件夹%windir%\ Microsoft.NET \ Framework [64] \ 中
    • 例如,64位版本的默认路径为%windir%\ Microsoft.NET \ Framework64 \ v4.0.30319 \ InstallUtil.exe

2.1.4.1 安装服务

  • installutil MyNewService.exe

2.1.4.2 卸载服务

  • installutil /u MyNewService.exe

2.1.5 调试服务

2.1.5.1 调试符号与pdb文件

  • 调试符号

    • 指编译器在将源文件编译为可执行程序的过程中,为支持调试而摘录的调试信息

      • 主要包括源文件名、变量名、函数名、对应的行号等等
    • 这些信息以表格的形式记录在符号表中
  • pdb文件
    • program debug database
    • 主要存储了调试符号
    • Visual Studio编译时生成的文件
      • 每个程序集都有一个与之对应的pdb文件

2.1.5.2 方式一:附加到服务进程

  • 服务必须是debug版本
  • 服务处于已安装、正在运行的状态
  • 在Visual Studio“调试”或者“工具”菜单中点击“附加到进程”
    • 在调试系统进程时,需要设置Microsoft符号服务器
    • 工具=>选项=>调试=>符号=>Microsoft符号服务器
  • 选择需要调试的服务进程后即进入调试模式
  • 限制
    • 调试服务的OnStart()、Main()方法比较麻烦

      • 附加到服务进程时,服务已处于运行状态,Main()以及OnStart()方法已经执行完毕

2.1.5.3 方式二:修改应用程序输出类型

  • 发布服务时输出类型设置为Windows应用程序
  • 调试时将输出类型更改为控制台应用程序
    • 需要调整OnStart()和OnStop()方法的调用方式

      • 服务的OnStart()和OnStop()方法是由系统服务管理器调用的
      • 更改为控制台应用程序后则由控制台应用程序调用
    • 需要在Main()方法中调用调整后的方法
      • Environment.UserInteractive判断是否在交互模式
public partial class Service1 : ServiceBase
{...internal void TestStartupAndStop(string[] args)  {  this.OnStart(args);  Console.ReadLine();  this.OnStop();  }
}
static class Program
{/// <summary>/// 应用程序的主入口点。/// </summary>static void Main(string[] args){if (Environment.UserInteractive){Service1 service1 = new Service1();service1.TestStartupAndStop(args);}else{ServiceBase[] ServicesToRun;ServicesToRun = new ServiceBase[]{new Service1()};ServiceBase.Run(ServicesToRun);}}
}

2.2 基于TopShelf创建服务

2.2.1 TopShelf

  • Topshelf是用于托管使用.NET Framework编写的服务的第三方框架
  • 服务的创建得到简化
    • 允许开发人员创建一个简单的控制台应用程序
    • 可以使用Topshelf将其安装为服务
  • 方便调试
    • 调试控制台应用程序比调试服务简单很多

2.2.2 配置TopShelf

  • 安装和引用TopShelf
  • 在Main()方法中配置TopShelf
class Program
{static void Main(string[] args){var rc = HostFactory.Run(x =>{x.Service<TownCrier>(s =>{s.ConstructUsing(name => new TownCrier());s.WhenStarted(tc => tc.Open());s.WhenStopped(tc => tc.Close());});x.RunAsLocalSystem();x.SetDescription("Sample Topshelf Host");x.SetDisplayName("Stuff");x.SetServiceName("Stuff");});var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());Environment.ExitCode = exitCode;}
}

2.2.3 安装和卸载TopShelf服务

  • 以管理员身份打开系统命令提示窗口
  • 将路径导航到服务应用程序所在文件夹
  • 输入命令进行安装和卸载

2.2.3.1 安装服务

  • MyNewService.exe install

2.2.3.2 卸载服务

  • MyNewService.exe uninstall

2.3 ServiceController

  • 指代Windows服务,并允许连接到正在运行或已停止的服务,对其进行操作或获取有关它的信息
  • 可以实现安装服务后自动启动服务
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{public ProjectInstaller(){InitializeComponent();}private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e){ServiceController serviceController = new ServiceController("Service1");serviceController.Start();}
}

2.4 定时服务

public partial class Service1 : ServiceBase
{...protected override void OnStart(string[] args){Timer timer = new Timer();timer.Interval = 60000;timer.Elapsed += new ElapsedEventHandler(this.OnTimer);timer.Start();}...public void OnTimer(object sender, ElapsedEventArgs args){...}
}

Windows服务应用程序相关推荐

  1. 演练:在组件设计器中创建 Windows 服务应用程序

    http://msdn.microsoft.com/zh-cn/library/zt39148a(v=vs.80).aspx 演练:在组件设计器中创建 Windows 服务应用程序 .NET Fram ...

  2. 【windows service】C# 创建Windows Service(Windows服务)程序

    C# 创建Windows Service(Windows服务)程序 很多年前大概08年做了一个windows桌面程序推送邮件给用户的程序,然后通过windows 计划任务每隔N分钟重复执行. 今天闲暇 ...

  3. .NET Windows服务应用程序

    此文旨在记录个人对windows服务的理解以及学习记录,高人可以直接绕行. 1.Windows 服务体系结构 @http://technet.microsoft.com/zh-cn/library/a ...

  4. C# 创建Windows Service(Windows服务)程序

    工具: Visual Studio Community 2015 写在前面: Windows可以在后台做一些任务,今天分享下Windows Service创建.安装.调试的方法以及一些异常问题的处理 ...

  5. Windows服务的程序方面的资料

    我在网上查找的Windows服务程序多是一样的教程,就是简单的一个线程或者是计时器,没有找到是对一个的项目的介绍的,就是只有服务的,没有还能够通过界面和服务交流的,不知道哪位高手指点一下 转载于:ht ...

  6. windows 服务 定时程序 跑不出数据

    void timer_Elapsed(object sender, ElapsedEventArgs e){DoSth();} private void DoSth(){try{_log.Info(& ...

  7. C#穿透session隔离———Windows服务启动UI交互程序

    在Windows服务里面启动其他具有界面的应用程序,需要穿透session隔离,尝试了很多种方法,都可行,现在一一列举下来,并写下几个需要注意的地方. 需要注意的地方 首先要将服务的Account属性 ...

  8. 用.NET创建Windows服务

    用.NET创建Windows服务 译者说明:我是通过翻译来学习C#的,文中涉及到的有Visual Studio.NET有关操作,我都根据中文版的VS.NET显示信息来处理的,可以让大家不致有误解. 作 ...

  9. 更上层楼:动态安装你的windows服务

    前言:先说明一下本文示例windows服务的简单需求,即根据外部配置实现不同方式记录日志的功能.记录日志的方式有三种,分为文本记录.数据库记录以及文本和数据库同时记录日志.如您所知,这个功能基本上没有 ...

最新文章

  1. python 输入文件名查找_Python实现的根据文件名查找数据文件功能示例
  2. xDeepFM架构理解及实现
  3. android添加截图功能,Android应用开发之Android 5.0及以上编程实现屏幕截图功能的方法...
  4. 主机通过sftp传输文件到某台服务器ubuntu虚拟机出现:open for write: permission denied
  5. Android 实现ListView圆角效果
  6. 腾讯,字节等大厂面试真题汇总,深夜思考
  7. 论坛的搭建以及优化方案
  8. gulp教程之gulp-imagemin压缩图片
  9. WebGL难以置信的神奇效果
  10. [技术贴]网络共享与便携式WiFi热点之USB绑定模式
  11. IE6升级到IE11兼容性问题和操作手册
  12. 小波变换第2讲:尺度函数与小波函数
  13. 工件SSMwar exploded 部署工件时出错。请参阅服务器日志了解详细信息
  14. 城市夜景照明对于安科瑞智能照明系统的运用
  15. nginx 之 http 转 https (两种方式)
  16. c++ shared_ptr的reset(), get()
  17. #第六章 四维股市理论数学模型基础6.1四维股市拟合理论的数学基础
  18. win10分屏设置一边竖屏_win10系统电脑屏幕竖屏改为横屏的详细办法
  19. 字符串关键字的散列映射
  20. Java拆分为姓和名

热门文章

  1. 国内ce认证机构有哪些 国内十大CE认证机构排名 做ce认证的公司推荐
  2. 哔咔服务器无响应,哔咔哔咔漫画进不去怎么办 无法进入解决办法
  3. 功能: Form窗口最大化时,控件相对位置变化的问题 (学习日记2016-12-23)
  4. Sun公司,Oracle公司(10.8)
  5. background-image属性
  6. 易语言制作提示类对话框
  7. python动态柱状图_动态排名柱状图的两种做法
  8. Integrate就医服务平台
  9. Win10使用FTP实现手机访问电脑FTP服务
  10. AI“头雁”百度的进取之道:善弈者通盘无妙手