Windows Service结合调试+相关资料 之我见
2011-07-19 11:01 沐海 阅读(1508) 评论(4) 编辑 收藏 举报Windows Service 需要3种程序:
服务程序
服务控制程序
服务配置程序
————————————————————
服务程序
服务程序需要3个部分:
主函数
service-main函数
处理程序
有关一个SCM(服务控制管理器)。可以把启动或停止服务的请求发给服务
——————————————————
SCM怎么与服务通信?
SCM发送启动服务请求给服务。 调用服务进程的主函数.服务发回SCM。scm为每一个服务都注册一个service-main函数。
主函数是服务程序的入口点。在这里service-main函数的入口点必须用SCM注册。
从主函数入口进入到service-main函数的入口。然后调用 来注册处理程序。然后SCM调用处理程序的启动。
——————————————————————————————————————
主函数
服务的主函数是程序的一般入口点。即Main()方法,它可以注册多个service-main函数
——————————————————
service-main函数
包含服务的实际功能。服务必须为所提供的每个服务注册一个service-main函数。
服务程序中可以在一个程序中提供许多服务。
SCM现在为每一个应该启动的服务调用service-main函数。
service-main函数的一个重要任务就是 注册一个处理程序。
——————————————————————————
处理程序
必须响应来自SCM的事件。服务可以停止、暂停、重新开始、。处理程序必须响应这些事件。
————————————————————
服务控制程序:可以控制服务,把控制代码发送给服务。处理程序应该响应这些事件。
服务配置程序:服务必须在注册表中配置。启动类型。用户和依赖关系。
Window 服务的类。
System.ServiceProcess名称空间中 实现服务的3部分的服务类。
服务程序====ServiceBase类
服务控制程序===ServiceController类
安装和配置类====ServiceProcessInstaller类和 ServiceInstaller类
(一一对应关系)
____________________(下面主要讲一下 关于 Windows服务需要的3中程序 之一 Windows服务程序)____________
Windows服务程序:
是一个没有屏幕的程序。所以VS设计器中并没有一些控件。
————————————————
1.服务程序类中 -- 设计器中--- 属性 --ServiceName =======对应的就是 管理工具--服务 中显示的 注册表中的服务的名称
还可以在 InitalizeComponent()方法中设置 ServiceBase的派生类的值。
『 private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "s";//这里设置了。前台设计器中的属性值也随之改变。 但必须要在初始化组件这个函数中才能对属性进行改变。
}
』
这个名称和下面对应
2. private System.ServiceProcess.ServiceInstaller serviceInstaller1;//被安装执行文件调用的实现的服务的类的实例
this.serviceInstaller1.ServiceName = "Services";//指向服务名称
首先由服务程序类来指定对应的 服务名称。然后再使用时,对应的服务都要对应 此服务程序类中设置的服务名称。
如果出现服务重名,已存在问题:
改变服务程序类对应的 服务名称。再改变,ServiceInstaller (服务安装类对象)指向的服务名称,即可。
——————————
Windows服务程序 在上面我们简单介绍过了。下面我再详细介绍一下。
上面说:
服务程序需要3个部分:
主函数
service-main函数
处理程序
这里 具体实现时。对应的3个部分和各个步骤。我进行详细的描述
----------------
ServiceBase类
是所有用.NET Framework 开发的Windows服务 的基类。
前面用到的Windows 服务程序就是派生自 此类。
Windows 服务程序类 中使用一个未归档的辅助类System.ServiceProcess.NativeMethods与SCM进行通信。
System.ServiceProcess.NativeMethods类是Win32API调用的包装类。ServiceBase类是内部的。因此不能在这里的代码中使用它。
当在服务应用程序中定义服务类时从 ServiceBase 派生。任何有用的服务均将重写 OnStart 和 OnStop 方法。对于其他功能,可以用特定行为重写 OnPause 和 OnContinue 来响应服务状态的更改。 服务是长时间运行的可执行文件,它不支持用户界面,在登录的用户帐户下可能无法运行。服务可以在没有任何用户登录计算机的情况下运行。 默认情况下,服务在“系统”帐户下运行,该帐户与“管理员”帐户不同。不能更改“系统”帐户的权限。或者,可以使用 ServiceProcessInstaller 指定运行服务时将使用的用户帐户。 一个可执行文件可以包含多项服务,但对每项服务均必须包含一个单独的 ServiceInstaller。ServiceInstaller 实例在系统中注册服务。安装程序还将每项服务与一个事件日志关联,您可以使用该日志记录服务命令。可执行文件中的 main() 函数定义哪些服务应该运行。服务的当前工作目录是系统目录,而不是可执行文件所位于的目录。 当启动某项服务时,系统将定位相应的可执行文件,并运行该服务的 OnStart 方法(它包含在可执行文件内)。但是,运行服务与运行可执行文件并不相同。可执行文件仅加载服务。服务则通过“服务控制管理器”访问(例如启动和停止)。 当您对服务首次调用“开始”时,可执行文件调用 ServiceBase 派生类的构造函数。在构造函数执行之后将立即调用 OnStart 命令处理方法。在服务首次加载之后,构造函数不会再次执行,因此有必要将构造函数执行的处理和 OnStart 执行的处理分开。可以由 OnStop 释放的任何资源都应在 OnStart 中创建。如果服务在 OnStop 释放资源后再次启动,那么,在构造函数中创建资源会妨碍这些资源的正确创建。 “服务控制管理器”(SCM) 提供与服务交互的方式。可以使用 SCM 将“开始”(Start)、“停止”(Stop)、“暂停”(Pause)、“继续”(Continue) 或自定义命令传递到服务中。SCM 使用 CanStop 和 CanPauseAndContinue 的值,决定服务是否接受“停止”、“暂停”或“继续”命令。仅当服务类中相应的属性 CanStop 或 CanPauseAndContinue 为 true 时,才会在 SCM 的上下文菜单中启用“停止”、“暂停”或“继续”。如果已启用,则相应的命令将传递到服务,并且调用 OnStop、OnPause 或 OnContinue。如果 CanStop、CanShutdown 或 CanPauseAndContinue 为 false ,则即使已实现相应的命令处理方法(如 OnStop),也不会予以处理。 可以使用 ServiceController 类通过编程实现 SCM 使用用户界面实现的功能。可以自动处理控制台中可用的任务。如果 CanStop、CanShutdown 或 CanPauseAndContinue 为 true ,但尚未实现相应的命令处理方法(如 OnStop),则系统引发异常并忽略该命令。 不必在 ServiceBase 中实现 OnStart、OnStop 或其他任何方法。然而,服务的行为在 OnStart 中加以描述,因此至少应重写该成员。可执行文件的 main() 函数通过调用 Run 方法,在服务控制管理器中注册可执行文件中的服务。传递给 Run 方法的 ServiceBase 对象的 ServiceName 属性必须与该服务的服务安装程序的 ServiceName 属性匹配。 可以使用 InstallUtil.exe 在系统中安装服务。 |
|
SCM、windows服务程序类、System.ServiceProcess名称空间中的类是怎么样相互作用的。
他们的作用的时间范围是在 服务的安装之后,首次启动时,调用onStart()方法之前,这些类之间的通信原理;
============================================
SCM这里你可以理解为 管理工具--服务--某个服务 --启动。
SCM启动应该启动的服务的进程。首先调用Main()方法。在服务的主要入口。然后调用Run()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | namespace WindowsService1 { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } } } |
Run()方法是用SCM中的NativeMethods.StartServiceCtrlDispatcher()方法 来 注册 ServiceMainCallBack()方法,并把记录写到事件日志中。
然后SCM调用已经注册的ServiceMainCallBack()方法。ServiceMainCallBack()本身使用NativeMethods.RegisterServiceCtrlHandler[EX]()方法在
SCM中注册处理程序。并在SCM中设置服务状态。
处理程序是在ServiceCommandCallBack()方法中执行的。
ServiceCommandCallBack()方法再把请求发送给OnStart()方法(即:调用OnStart()方法)。
在OnStart()方法中实现启动代码。如果OnStart()方法执行成功。就把字符串“Service Started Sucessful”写到事件日志中。
处理程序是在ServiceCommandCallBack()方法中执行的。
当改变了对服务的请求时。SCM就调用ServiceCommandCallBack()方法。
ServiceCommandCallBack()方法再把请求发送给OnStop()等方法。
++++++++++++++++++++
主函数
ServiceBase类的数组
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
如果这个服务进程中要运行多个服务。就需要把具体服务类的多个实例添加到数组中。
然后把数组传给 静态方法RUN();
使用RUN()方法,可以把SCM引用(一些处理程序等等。)提供给服务的入口点。 (MAIN---Service-Main)
服务进程的主线程现在处于停滞状态。等待服务的结束。
++++++++++++++++++
服务的启动
OnStart()方法必须返回给调用者(即ServiceBase类中的 ServiceMainCallBack()方法。)
ServiceBase类注册处理程序,并 在调用 OnStart()之前把服务成功启动 的消息通知给SCM。
++++++++++++++++++++++
关于服务的安装、监视、控制。下一篇再讲。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述