windows服务是如何被调用的?

 

1、服务介绍

操作系统在启动的时候,会启动一些不需要用户交互的进程。这些进程被称为服务。当操作系统启动后它就自动被运行。

2、组成

服务程序、服务控制程序(SCP,service control program)和服务控制管理器(SCM,service control manager)组成了Windows服务。我们可以通过SCP操纵SCM启动、暂停、停止服务程序。其中服务程序和SCP由我们自己编写。

SCM

servics.exe是操作系统内置的一个部件。建立数据库、启动服务(自启动),分配服务进程。

SCP

服务控制程序,例如windows自带的服务工具:

 

 

当然也可以自己写一个服务管理工具。

服务程序

我们需要执行的任务

3、执行原理

首先看看服务入口:

复制代码
  static void Main()   {       ServiceBase[] ServicesToRun;       ServicesToRun = new ServiceBase[]        {           new MainService()        };       ServiceBase.Run(ServicesToRun);  }
复制代码

从入口看,这和控制台程序一样,因为绝大部分的服务都不需要交互,所以没有用户界面。 那么ServiceBase.Run到底做了什么事情呢?平常情况下,我们并不关心,只是windows服务听起来有点神秘。于是就搜索关于windows service原理的文章,理解一下。如下图:

 

 大致原理:服务主线程调用StartServiceCtrlDispatcher,最终执行了ServiceMain回调,调用了我们自己写的服务代码。SCP通过CtrlHandle回调了我们对服务的一些操作,比如暂停,启动等等。它们都通过SetServiceStatus方法与SCM通信,把服务的状态等信息及时地告诉SCM。我结合代码主要介绍下,我们的服务代码是如何被调用的。

Main方法中的ServiceBase是一个什么样的类呢?

 从继承关系上看,它是可以跨应用程序域调用(MarshalByRefObject——Enables access to objects across application domain boundaries in applications that support remoting)以及需要释放资源(IDisposable)。这说明,可以远程调用服务以及服务占用了非托管资源。

我们看Run方法:

复制代码
 1         public static void Run(ServiceBase[] services)  2         {  3             if ((services == null) || (services.Length == 0))  4             {  5                 throw new ArgumentException(Res.GetString("NoServices"));  6             }  7             if (Environment.OSVersion.Platform != PlatformID.Win32NT)  8             {  9                 string message = Res.GetString("CantRunOnWin9x"); 10                 string title = Res.GetString("CantRunOnWin9xTitle"); 11                 LateBoundMessageBoxShow(message, title); 12             } 13             else14             { 15                 IntPtr entry = Marshal.AllocHGlobal((IntPtr) ((services.Length + 1) * Marshal.SizeOf(typeof(System.ServiceProcess.NativeMethods.SERVICE_TABLE_ENTRY)))); 16                 System.ServiceProcess.NativeMethods.SERVICE_TABLE_ENTRY[] service_table_entryArray = new System.ServiceProcess.NativeMethods.SERVICE_TABLE_ENTRY[services.Length]
                    
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信