了解 Windows 服务体系结构

 

上一次修改主题: 2005-05-23

Windows 服务(也称服务应用程序)是无论用户是否登录都运行在 Windows 计算机上的应用程序。Windows 服务包含一个可执行文件、一个存储应用程序组件的目录,以及定义服务参数的注册表设置。Windows 服务实现一个可编程的接口,SCM 可以使用该接口来控制服务。Windows 服务既可以在系统启动时自动启动,也可以由用户使用服务控制程序来手动启动。服务控制程序是使用 SCM 功能来控制服务的应用程序。例如,“服务”工具和命令行工具 net.exe 和 SC.exe 就是服务控制程序。

下列图说明了 Windows 服务体系结构。

ca48e350-ed32-4789-988f-9f28dc0567b6

note注意:
SCM 进程是一个远程过程调用 (RPC) 服务器服务。为了控制远程计算机上的服务,服务控制程序使用 RPC 在本地或通过网络与 SCM 通信。

服务控制管理器的职责

SCM(也称服务控制器)是一个一般的 Windows 进程,它执行各种与服务有关的任务。这些任务将在后续各节详细介绍。

为安装的服务维护一个数据库

为使 Windows 能够成功启动,SCM 为安装的所有服务维护一个数据库,其中包括所有服务和设备驱动程序列表。在附加服务(如 Exchange Server 2003 服务)安装到服务器上后,相应的条目会添加到服务数据库中。SCM 在以下注册表位置维护此数据库:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

对于安装的每个服务和驱动程序,服务数据库中都包含一个相应的项。项的名称对应于服务配置程序安装服务时所指定的服务名。例如,“MSExchangeIS”是 Microsoft Exchange Information Store 服务的名称,而“MSExchangeSA”是 Microsoft Exchange System Attendant 服务的名称。服务名的最大长度为 256 个字符。

下图显示了注册表中与 Exchange 有关的几个服务条目。

2c8c4abe-979d-4757-a34b-57339cfc5eca

note注意:
使用“服务”工具时所能看到的名称是 Windows 服务的显示名。例如,“MSExchangeSA”的显示名为“Microsoft Exchange System Attendant”。显示名在名为 DisplayName 的 REG_SZ 值中定义。可以在如下注册表项的下面找到 DisplayNameHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<服务名>

锁定和解锁服务数据库

为了能够连续访问配置信息,SCM 必须在 SCM 初始化期间锁定服务数据库。例如,SCM 在启动服务之前先锁定服务数据库,这样在服务启动时便不能更改服务配置。在服务启动完成后,SCM 解除锁定。要在重新配置服务之前请求锁定,以及在配置完成后解除锁定,服务配置程序还必须与 SCM 通信。可以使用 SC.exe 命令行工具和 sc QueryLock 命令来查看服务数据库是否已被锁定。

note注意:
应记住的一点是,当管理需要很长时间才能启动的服务时,不能在服务启动过程中重新配置启动类型或其他配置设置,因为 SCM 锁定了服务数据库。只能在服务启动之前或之后应用配置更改。

枚举安装的服务

SCM 进程从服务数据库中读取每一个注册表项,以便为每一个服务创建一个服务记录。服务记录包含服务名、启动类型、服务状态(例如,服务和可接受控制代码的当前状态)以及指向依存列表的指针。SCM 使用这些服务记录并根据其当前状态和依存关系来确定哪些操作对于服务是有效的。例如,如果有另一个依赖系统助理的服务(如 Microsoft Exchange Information Store 服务)正在运行,则不能在“服务”工具中停止系统助理。

启动、停止、暂停或继续服务

在执行常规任务(如启动或停止服务)时,SCM 与它所控制的服务通信。SCM 可以在系统启动时自动启动 Windows 服务(自动启动服务),或者根据服务控制程序的要求手动启动 Windows 服务(按需启动服务)。但是,如果自动启动服务依赖按需启动服务,按需启动服务也将自动启动。启动类型还可以确定服务是否被禁用。如果被禁用,将无法启动。您无法启动依赖已禁用服务的自动启动服务或按需启动服务。这种依存关系值得注意,尤其是在计划禁用服务(例如,在运行 Exchange Server 的前端服务器上)时更应如此。不得禁用基本服务。否则,操作系统将无法启动,因为被禁用的服务使得依赖于它的其他所有服务无法启动。如果在禁用服务后出现启动问题,请不要登录到 Windows 上。此时,应使用“最后一次正确”的配置重新启动系统,以丢弃最近对服务配置所作的更改。Windows 将“最后一次正确”的配置存储在 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001 注册表项中,并在您每次成功登录到操作系统时更新此注册表项。使用错误的配置登录到 Windows 上时,会将错误的设置应用于“最后一次正确”的配置。

要快速验证 Exchange 服务的依存关系和启动类型,可以使用 SC.exe 工具和 sc <service name> qc 命令。例如,下面的输出代表系统助理的标准配置(命令行:“sc qc MSExchangeSA¡±£©£º

SERVICE_NAME: MSExchangeSA

TYPE : 10 WIN32_OWN_PROCESS

ERROR_CONTROL : 1 NORMAL

BINARY_PATH_NAME : "C:\Program Files\Exchsrvr\bin\mad.exe"

LOAD_ORDER_GROUP :

TAG : 0

DISPLAY_NAME : Microsoft Exchange System Attendant

SERVICE_START_NAME : LocalSystem

要确定启动类型,请从“服务”工具中,单击“常规”选项卡,然后单击“启动类型”。还可以使用“服务”工具启动系统助理,或者使用 SC.exe 和命令行 sc start MSExchangeSA 启动系统助理。还可以使用 net start 命令启动服务,如 net start MSExchangeSA。大多数管理员倾向于使用“服务”工具。

无论您使用“服务”工具、SC.exe、net start 命令,还是其他任何服务控制程序,SCM 都通过依次执行下列步骤来启动服务:

  1. 检索存储在服务数据库中的帐户信息
    服务帐户的用户名和密码是在安装服务时指定的。SCM 将用户名存储在各个服务的注册表项(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<服务名>)名为 ObjectName 的 REG_SZ 注册表值中。密码位于本地安全机构 (LSA) 的一个安全部分。可以使用“登录”选项卡更改“服务”工具中的服务帐户。

    note注意:
    Exchange Server 2003 服务默认使用 LocalSystem 帐户。LocalSystem 帐户是预定义的本地帐户,它在本地计算机上具有广泛的特权。此帐户仅供系统进程使用,并且没有密码。
  2. 登录服务帐户
    所有活动的进程都必须在 Windows 中拥有标识,服务应用程序也不例外。启动服务时,SCM 使用从服务数据库中获取的帐户信息登录到 Windows 上。在本地计算机上,SCM 用来登录的帐户必须具有特殊的“作为服务登录”用户权利。

    note注意:
    LocalSystem 帐户隐含地具有“作为服务登录”权利,因为该帐户对所有本地资源都具有完全访问权限。
  3. 创建处于挂起状态的服务
    SCM 启动处于挂起状态的新服务,因为此类服务只有在 SCM 在新进程中添加了所需的安全信息后才可以使用。

  4. 为进程分配访问令牌
    在 Windows 中执行的每个进程都需要一个访问令牌(也称登录令牌)。访问令牌是描述服务的安全上下文的对象。令牌中的信息包括服务帐户的标识和特权,服务使用这些信息与操作系统交互。

  5. 允许进程执行
    在完成登录过程并分配访问令牌后,SCM 可以允许服务运行,允许其执行自己的功能。

SCM 在停止服务时依次执行下列步骤:

  1. SCM 接收服务的停止请求
    使用服务控制功能,服务控制程序可以通过 SCM 向服务发送 SERVICE_CONTROL_STOP 请求,以此来停止服务。
  2. SCM 检查服务依存关系
    如果 SCM 确定正在运行的其他服务依赖于停止请求中指定的服务,便会向服务控制程序返回错误代码。在触发停止过程之前,服务控制程序必须枚举并停止依赖于指定服务的所有服务。例如,“服务”工具显示“停止其他服务”对话框,该对话框询问您是否还要停止依赖于该服务的所有服务。但是,SC.exe 仅仅报告失败代码,并指出因为有其他活动的服务依赖于该服务,服务无法停止。
  3. SCM 将停止请求转发给服务
    如果未检测到有其他活动的服务依赖于该服务,SCM 便会通过将停止代码转发给指定的服务来指示该服务停止运行。该服务现在必须释放分配给它的资源并关闭。

维护正在运行的服务的状态信息

服务运行时,会向 SCM 进程发送状态通知。SCM 在每个服务的服务记录中维护此状态信息。SCM 跟踪此信息,以确保不会错误地发送不符合接收方服务的当前状态的控制请求。

服务状态信息包括:

  • 服务类型 服务可以是文件系统驱动程序、设备驱动程序或 Windows 服务,并且既可以运行它自己的进程,也可以与其他服务共享一个进程。例如,系统助理就是运行它自己的进程的服务,而 SMTP 服务则是与集成到 Internet 信息服务 (IIS) 中的其他服务共享一个进程的服务。
  • 当前状态 服务状态可以是正在启动、正在运行、暂停、正在停止或未运行。
  • 可接受的控制代码 服务能够根据当前的状态在其处理职能内接受和处理的控制代码。
  • Windows 退出代码 使用此代码报告在启动或停止时发生的错误。要返回特定于服务的错误代码,服务必须将该值设置为 ERROR_SERVICE_SPECIFIC_ERROR,以指出可以在服务退出代码中找到更多信息。如果服务正常运行或停止,则将该值设置为 NO_ERROR。
  • 服务退出代码 服务使用此代码报告在启动或停止时发生的错误。除非 Windows 退出代码设置为 ERROR_SERVICE_SPECIFIC_ERROR,否则,该值会被忽略。
  • 等待线索 服务使用此代码报告即将到来的启动、停止、暂停或继续运行等操作大概所需的时间(毫秒)。
  • 检查点 在冗长的启动、停止、暂停或继续运行过程中,服务使用该值定期报告其进度。例如,“服务”工具使用该值跟踪服务在启动和停止操作中的进度。
tip提示:
要显示所有 Windows 服务当前的状态,可以使用 sc query state= all type= service 命令。

Exchange 服务和 LocalSystem 帐户

Exchange Server 2003 服务运行在 LocalSystem 帐户下。这具有下列安全含义:

  • 无需额外的服务帐户或密码更改 LocalSystem 帐户 (NT AUTHORITY\LocalSystem) 始终存在,并且其密码为随机的十六进制数。此密码每七天自动更改一次,这样,您便无需在安装 Exchange Server 2003 之前在 Active Directory 中创建服务帐户,或者频繁地更改服务密码。

  • 对所有本地资源的完全控制权限 由于 Exchange Server 2003 服务对所有本地资源都具有完全控制权限,因为这些服务通常对注册表数据库、IIS 元数据库以及文件系统具有无限制的访问权限。但是,如果明确拒绝了特殊 Windows 帐户“SYSTEM”或“Everyone”帐户的访问权限(不推荐这样做),则上述说法不成立。因此,如果域控制器上安装了 Exchange 2003,Exchange Server 2003 服务将对 Active Directory 具有完全访问权限,因为域控制器上驻留了一个目录副本,并且 LocalSystem 对本地资源具有完全访问权限。

    note注意:
    大多数安全意识较强的组织都不选择在域控制器上安装 Exchange Server 2003,因为这种安装无法实现 Exchange Server 2003 和 Active Directory 的分别管理。
  • LocalSystem 只能访问本地资源 如果服务运行在 LocalSystem 帐户下,将只能访问本地资源。在这种情况下,要访问网络资源,必须使用另一个帐户。因此,运行在 LocalSystem 下的服务使用 NetworkService 帐户来访问网络资源。该帐户的名称为 NT AUTHORITY\NetworkService。该帐户没有密码。
    NetworkService 帐户对应于域中本地计算机的计算机帐户。运行在 LocalSystem 帐户的安全上下文中的 Exchange 服务在通过网络访问域资源(如 Active Directory)时,使用本地计算机帐户凭据。因此,Exchange Server 2003 在成员服务器上所拥有的特权比在域控制器上要少得多,因为计算机帐户在默认情况下只有很少的特权,并且不属于任何组。默认配置下的计算机帐户只能对 Active Directory 进行最低限度的访问。
    要解决此问题并为计算机帐户授予必要的权限,Exchange Server 2003 在 Active Directory 中创建下面两个特殊的安全组:

    • Exchange Domain Servers Exchange Domain Servers 是一个全局安全组,它包含域中运行 Exchange Server 的所有服务器的计算机帐户。
    • Exchange Enterprise Servers Exchange Enterprise Servers 是一个本地安全组,它包含目录林中的所有全局 Exchange Domain Servers 组。此安全组对所有 Exchange 计算机帐户都授予对本地域中的必要资源的访问权限。
    note注意:
    不要重命名或移动 Exchange Domain Servers 或 Exchange Enterprise Servers 安全组,也不要将现有的 Exchange 服务器的计算机帐户从这些组中删除。

检查服务数据库

当在注册表编辑器 (Regedit.exe) 中打开 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,并检查 Exchange 服务的各个注册表项时,您会发现随同 MSExchange 一起启动的许多服务的服务注册表项下都包含类似的值。下表列出了这些值。

Windows 服务的常规注册表值

类型 描述
DependOnGroup

REG_MULTI_SZ

列出 Windows 服务所依赖的加载顺序组。如果依赖于某个组的服务在尝试安装该组的所有成员后,该组至少有一个成员运行,则该服务便可以运行。

DependOnService

REG_MULTI_SZ

列出该服务所依赖的 Windows 服务的名称。SCM 必须在启动该服务之前先启动这些服务。如果该服务没有依赖项,该值可以为空字符串。

Description

REG_SZ

描述该服务。该描述仅仅是一个说明服务用途的注释。

DiagnosticsMessageFile

REG_SZ

包含资源 DLL 的名称,这些资源 DLL 包含服务写入到应用程序事件日志中的那些事件的事件描述字符串。资源 DLL 位于 \Program Files\Exchsrvr\Res 目录中。

DisplayName

REG_SZ

包含用来标识服务的显示名。该字符串最多可以有 256 个字符。SCM 保留名称的大小写。比较显示名时总是忽略大小写。

ErrorControl

REG_DWORD

指出错误的严重性,并指出在该服务启动失败时应采取的操作。此参数确定下面的某一种操作:

  • 启动程序记录错误,但继续启动操作。
  • 启动程序记录错误并显示消息,但继续启动操作。
  • 启动程序记录错误。如果“最后一次正确”的配置启动,启动操作将继续。否则,系统将使用“最后一次正确”的配置重新启动。
  • 启动程序在可能的情况下记录错误。如果“最后一次正确”的配置启动,系统启动将被取消。否则,系统将使用“最后一次正确”的配置重新启动。
FailureActions

REG_BINARY

引用 SCM 在每次服务失败时应采取的操作。如果服务在停止时未向服务控制器报告状态(例如,当服务失败时),系统将认为服务失败。

Group

REG_SZ

命名该服务所属的加载顺序组。请注意,设置该值会覆盖 DependOnService 值的设置。

ImagePath

REG_EXPAND_SZ

包含服务二进制文件的完全限定路径。如果该路径包含空格,必须将它用引号括起来,这样才能对它进行正确的解析。例如 "d:\\Program Files\\Exchsvr\\Bin\\mad.exe"。

该路径还可以包含程序参数。

ObjectName

REG_SZ

指定服务应运行在哪个帐户名下。如果服务使用 LocalService 帐户,该参数将设置为 NT AUTHORITY\LocalService。还可以指定 DomainName\UserName 形式的帐户名。

Start

REG_DWORD

指定何时启动服务。SCM 可以在系统启动期间或在进程请求服务启动时自动启动服务。该值还可以指出:不能启动服务,如果试图启动该服务,将产生错误代码 ERROR_SERVICE_DISABLED。

Tag

REG_DWORD

确定加载顺序组中的服务启动顺序。标记只能用于驱动程序服务。

Type

REG_DWORD

将服务类型指定为文件系统驱动程序、设备驱动程序、运行其自己的进程的服务,或者与一个或多个其他服务共享一个进程的服务。例如,MSExchangeSA 就是运行它自己的进程的服务,而 EXIFS 则是 Exchange 特有的文件系统驱动程序。

此外,还可能存在与 Exchange 服务对应的下列子项:

  • Diagnostics 该项包含服务可能提供的事件日志类别的 REG_DWORD 参数。位于该注册表项下面的参数的名称依次由资源标识号和字符串组成,如“9 Clean Mailbox”。与每个参数关联的值表示该类别的诊断日志记录级别。通常,通过 Exchange 系统管理器中的服务器属性配置这些值。“诊断日志记录”选项卡列出各种类别,并将选定的值分配给这些参数。
  • Enum 该注册表项所包含的参数供 SCM 用来枚举服务数据库中的服务。例如,REG_SZ 参数 0 包含一个值,该值引用 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root 注册表项下面的子项。这样,Windows 配置管理器便可以在系统启动期间将服务作为逻辑设备枚举出来。
  • Parameters 该注册表项包含与服务器特有的配置信息对应的注册表参数。Parameters 项还可以包含子项。
  • Performance 该注册表项提供性能监视计数器。REG_SZ 参数 Library 指定包含性能计数器的 DLL。关于性能计数器,存在更多的注册表项。例如,REG_SZ 参数 PerfIniFile 引用定义各个性能计数器的 .ini 文件。
  • Security 该注册表项存放名为 Security 的 REG_BINARY 参数,该参数包含可指定哪些帐户能够控制服务的服务安全描述符。例如,管理员可能有权启动和停止服务,而普通用户则不能。
Caution警告:
错误地编辑注册表可能导致严重问题,甚至可能需要重新安装操作系统。因注册表编辑不当而导致的问题可能没有办法解决。在编辑注册表之前,请备份所有重要数据。