Windows服务应用程序
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启动而启动
二、创建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()的设置
- 可通过属性对服务进行重命名
- 可通过属性对服务进行重命名
- 包含设计和代码视图,类似WinForms
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对象
- 一个服务可执行文件可能包含两个服务
- 由安装实用程序(例如InstallUtil.exe)调用
- 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()方法已经执行完毕
- 调试服务的OnStart()、Main()方法比较麻烦
2.1.5.3 方式二:修改应用程序输出类型
- 发布服务时输出类型设置为Windows应用程序
- 调试时将输出类型更改为控制台应用程序
- 需要调整OnStart()和OnStop()方法的调用方式
- 服务的OnStart()和OnStop()方法是由系统服务管理器调用的
- 更改为控制台应用程序后则由控制台应用程序调用
- 需要在Main()方法中调用调整后的方法
- Environment.UserInteractive判断是否在交互模式
- 需要调整OnStart()和OnStop()方法的调用方式
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服务应用程序相关推荐
- 演练:在组件设计器中创建 Windows 服务应用程序
http://msdn.microsoft.com/zh-cn/library/zt39148a(v=vs.80).aspx 演练:在组件设计器中创建 Windows 服务应用程序 .NET Fram ...
- 【windows service】C# 创建Windows Service(Windows服务)程序
C# 创建Windows Service(Windows服务)程序 很多年前大概08年做了一个windows桌面程序推送邮件给用户的程序,然后通过windows 计划任务每隔N分钟重复执行. 今天闲暇 ...
- .NET Windows服务应用程序
此文旨在记录个人对windows服务的理解以及学习记录,高人可以直接绕行. 1.Windows 服务体系结构 @http://technet.microsoft.com/zh-cn/library/a ...
- C# 创建Windows Service(Windows服务)程序
工具: Visual Studio Community 2015 写在前面: Windows可以在后台做一些任务,今天分享下Windows Service创建.安装.调试的方法以及一些异常问题的处理 ...
- Windows服务的程序方面的资料
我在网上查找的Windows服务程序多是一样的教程,就是简单的一个线程或者是计时器,没有找到是对一个的项目的介绍的,就是只有服务的,没有还能够通过界面和服务交流的,不知道哪位高手指点一下 转载于:ht ...
- windows 服务 定时程序 跑不出数据
void timer_Elapsed(object sender, ElapsedEventArgs e){DoSth();} private void DoSth(){try{_log.Info(& ...
- C#穿透session隔离———Windows服务启动UI交互程序
在Windows服务里面启动其他具有界面的应用程序,需要穿透session隔离,尝试了很多种方法,都可行,现在一一列举下来,并写下几个需要注意的地方. 需要注意的地方 首先要将服务的Account属性 ...
- 用.NET创建Windows服务
用.NET创建Windows服务 译者说明:我是通过翻译来学习C#的,文中涉及到的有Visual Studio.NET有关操作,我都根据中文版的VS.NET显示信息来处理的,可以让大家不致有误解. 作 ...
- 更上层楼:动态安装你的windows服务
前言:先说明一下本文示例windows服务的简单需求,即根据外部配置实现不同方式记录日志的功能.记录日志的方式有三种,分为文本记录.数据库记录以及文本和数据库同时记录日志.如您所知,这个功能基本上没有 ...
最新文章
- python 输入文件名查找_Python实现的根据文件名查找数据文件功能示例
- xDeepFM架构理解及实现
- android添加截图功能,Android应用开发之Android 5.0及以上编程实现屏幕截图功能的方法...
- 主机通过sftp传输文件到某台服务器ubuntu虚拟机出现:open for write: permission denied
- Android 实现ListView圆角效果
- 腾讯,字节等大厂面试真题汇总,深夜思考
- 论坛的搭建以及优化方案
- gulp教程之gulp-imagemin压缩图片
- WebGL难以置信的神奇效果
- [技术贴]网络共享与便携式WiFi热点之USB绑定模式
- IE6升级到IE11兼容性问题和操作手册
- 小波变换第2讲:尺度函数与小波函数
- 工件SSMwar exploded 部署工件时出错。请参阅服务器日志了解详细信息
- 城市夜景照明对于安科瑞智能照明系统的运用
- nginx 之 http 转 https (两种方式)
- c++ shared_ptr的reset(), get()
- #第六章 四维股市理论数学模型基础6.1四维股市拟合理论的数学基础
- win10分屏设置一边竖屏_win10系统电脑屏幕竖屏改为横屏的详细办法
- 字符串关键字的散列映射
- Java拆分为姓和名