65.9K
CodeProject 正在变化。 阅读更多。
Home

CNTService v1.06 - NT 服务框架

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (16投票s)

2000 年 3 月 4 日

viewsIcon

309653

downloadIcon

4509

用于在 MFC 中开发 NT 服务的类框架。

  • 下载源代码文件 - 41 Kb
  • 引言

    欢迎使用 CNTService,这是一组免费的 MFC 类,提供了一个用于在 MFC 中开发 NT 服务的类框架。

    有关 NT 服务的详细信息,如何开发它们以及它们与其他 NT 子系统的关系,我建议您仔细阅读 Platform SDK 附带的相关文档。


    特点
    用法
    历史
    类框架参考
    计划增强功能
    参考文献
    联系作者


    特点

    • 使用虚函数的简单、干净的 C++ 接口。
    • 所有代码都启用了 Unicode,并提供了构建配置。
    • 所有代码在最高警告级别 4 下都能干净地编译。我网站上的所有其他代码也是如此。
    • 内置持久化函数,提供类似于内置 MFC 注册表/ini 函数的支持。
    • 提供了一个简单的测试服务,以帮助您开始开发自己的 NT 服务。
    • 为所有类都提供了全面的文档。


    用法

    • 请记住,这些类是高度 NT 特定的,这些代码在 95/98 上无法正常工作。这两个操作系统都为服务提供了一些支持,但其方式与 NT 服务完全不兼容。
    • 要在您的代码中使用这些类,只需将 ntserv.cpp 包含到您的项目中,并在需要调用该类的任何模块中 #include ntserv.h,然后从 CNTService 派生您自己的服务类并重写必要的功能。
    • 您还需要将 ntserv_msg.mc 的已编译形式包含到您的服务可执行文件的资源文件中。有关此内容的更多信息,请参见下文 v1.06 的历史记录详情。
    • 要查看该类如何工作,请查看 "app.cpp" 模块中的 InitInstance() 代码。
    • 您的代码需要静态或动态地包含 MFC。


    历史

    V1.0 (1998 年 7 月 17 日)
    • 首次公开发布。

    1998 年 8 月 24 日

    • 对演示程序 (app.cpp) 进行小更新,以消除编译器错误。

    V1.01 (1999 年 5 月 17 日)

    • 添加了许多 ASSERT 语句以帮助调试。
    • 修复了 Marin Kunev 报告的 CNTEventLogSource::Report() 中的一个错误。
    • 修复了使用 VC 6 编译时出现的编译器警告。

    V1.02 (1999 年 9 月 5 日)

    • 添加了更多 ASSERT 语句以帮助调试。

    V1.03 (1999 年 10 月 3 日)

    • CNTService 类中添加了 GetProfileStringArray()WriteProfileStringArray()GetProfileBinary()WriteProfileBinary() 方法。
    • 重命名了一些模块名称。

    V1.04 (1999 年 10 月 5 日)

    • 修复了 release 和 Unicode 构建配置的 mc 文件编译问题。
    • 使用 VC++ 6 构建时修复了级别 4 警告。

    V1.05 (1999 年 10 月 10 日)

    • 增加了对 Windows 2000 服务描述字段的支持。
    • 添加了服务名称、友好名称和描述文本的访问器函数。

    V1.06 (2000 年 1 月 24 日)

    • 修改了 mc 文件包含到 TestSrv.exe 示例服务的方式。mc 文件现在被编译成一个中间 ntserv_msg.rc 文件,然后 #include 到最终的 rc 文件 testsrv.rc 中。这样做是为了让 testsrc.rc 文件可以在 Visual C++ 的资源设计器中进行编辑。在 CNTService 的先前版本中,如果您尝试编辑由 MC 命令行编译器生成的 rc 文件,您会损坏该文件。如果您使用 CNTService 开发自己的服务,我建议您采用这种方法。您需要做的是在 VC++ 中创建一个资源脚本,添加您希望包含在服务资源中的任何资源(例如,版本信息、字符串等),然后打开资源包含对话框,并修改编译时指令以 #include "ntserv_msg.rc" 或您通过编译 .mc 文件生成的 mc 文件的版本。您还应该查看 CNTService 提供的演示服务中的项目设置,以了解它如何通过批处理文件处理 .mc 文件的编译(右键单击 ntserv_msg.mc 并选择设置)。


    类框架参考

    该框架包含以下类

    CNTServiceCommandLineInfo
    CNTEventLogSource
    CNTService
    CNTScmService
    CNTServiceControlManager
    CEventLogRecord
    CNTEventLog


    CNTServiceCommandLineInfo

    CNTServiceCommandLineInfo 类有助于在应用程序启动时解析命令行。它的工作方式几乎与 MFC 中的 CCommandLineInfo 类完全相同。

    服务应用程序通常会在您的 main/wmain 或 InitInstance() 函数中创建一个该类的本地实例。然后将此对象传递给 CNTService::ParseCommandLine(),后者会填充 CNTServiceCommandLineInfo 对象。然后将 CNTServiceCommandLineInfo 对象传递给 CNTService::ProcessShellCommand() 以处理命令行参数和标志。

    您可以使用此对象封装以下命令行选项和参数

    命令行参数 执行的命令
    app /install 安装服务。
    app /remove | /uninstall 卸载服务。
    app /help 调用虚函数 CNTService::OnHelp()

    CCommandLineInfo 派生一个新类来处理其他标志和参数值。


    CNTEventLogSource

    CNTEventLogSource 提供了一个包装类,用于将事件写入 NT 事件日志。您可以将其视为 Event log API 的服务器端。

    此类提供的函数包括

    CNTEventLogSource
    ~CNTEventLogSource
    operator HANDLE
    Attach
    Detach
    Register
    报表
    Deregister
    Install
    Uninstall


    CNTEventLogSource::CNTEventLogSource

    CNTEventLogSource();

    备注
    这是默认构造函数,它会将所有内部变量初始化为安全状态。

    另请参阅
    ~CNTEventLogSource


    CNTEventLogSource::~CNTEventLogSource

    ~CNTEventLogSource();

    备注
    这是该类的标准析构函数。它会在内部调用 Deregister 以确保关闭此实例打开的任何句柄。

    另请参阅
    CNTEventLogSource, Deregister


    CNTEventLogSource::operator HANDLE

    operator HANDLE() const;

    返回值
    代表此事件日志源的底层 SDK 句柄。

    备注
    此函数公开了 CNTEventLogSource 类包装的底层句柄。此函数用于与直接使用句柄的旧代码集成。


    CNTEventLogSource::Attach

    BOOL Attach(HANDLE hEventSource);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • hEventSource -- 从 ::RegisterEventSource() 返回的 SDK 事件日志源句柄。

    备注
    使用此成员函数将现有 SDK 句柄附加到 CNTEventLogSource

    另请参阅
    Detach


    CNTEventLogSource::Detach

    HANDLE Detach();

    返回值
    SDK 事件日志源句柄。

    备注
    调用此函数以将 m_hEventLogSource 与 CNTEventLogSource 对象分离,并将 m_hEventLogSource 设置为 NULL。

    另请参阅
    Attach


    CNTEventLogSource::Register

    BOOL Register(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • lpUNCServerName -- 指向一个以 null 结尾的字符串,该字符串指定了要在此操作上执行的服务器的通用命名约定 (UNC) 名称。如果此参数为 NULL,则该操作将在本地计算机上执行。
    • lpSourceName -- 指向一个以 null 结尾的字符串,该字符串指定了返回句柄所引用的源的名称。源名称必须是注册表中 EventLog 键下的日志文件条目的子键。例如,如果注册表有以下键,则 WinApp 是一个有效的源名称

      HKEY_LOCAL_MACHINE
        System
          CurrentControlSet
            Services
              EventLog
                Application
                  WinApp
                Security
                System
      

    备注
    使用此函数注册一个日志源到事件日志。在内部,CNTService 类包含一个类型为 CNTEventLogSource 的成员变量 (m_EventLogSource),它在其构造函数中调用此函数。

    另请参阅
    Deregister


    CNTEventLogSource::Report

    BOOL Report(WORD wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, LPCTSTR* lpStrings, LPVOID lpRawData) const;
    BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString) const;
    BOOL Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2) const;
    BOOL Report(WORD wType, DWORD dwEventID, DWORD dwCode) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • wType -- 指定要记录的事件类型。此参数可以是以下值之一
      含义
      EVENTLOG_ERROR_TYPE 错误事件
      EVENTLOG_WARNING_TYPE 警告事件
      EVENTLOG_INFORMATION_TYPE 信息事件
      EVENTLOG_AUDIT_SUCCESS 成功审计事件
      EVENTLOG_AUDIT_FAILURE 失败审计事件
    • wCategory -- 指定事件类别。这是特定于源的信息;类别可以具有任何值。
    • dwEventID -- 指定事件。事件标识符指定与事件源关联的消息文件中的消息。
    • lpUserSid -- 指向当前用户的安全标识符。如果不需要安全标识符,则此参数可以为 NULL。
    • wNumStrings -- 指定 lpStrings 参数指向的数组中的字符串数量。值为零表示没有字符串。
    • dwDataSize -- 指定要写入日志的事件特定原始(二进制)数据的字节数。如果此参数为零,则不存在事件特定数据。
    • lpStrings -- 指向包含以 null 结尾的字符串数组的缓冲区,这些字符串将在事件查看器向用户显示字符串之前与消息文件中的消息合并。此参数必须是一个有效指针(或 NULL),即使 wNumStrings 为零。
    • lpRawData -- 指向包含二进制数据的缓冲区。此参数必须是一个有效指针(或 NULL),即使 dwDataSize 参数为零。
    • lpszString, lpszString1, lpszString2 -- 指定一个字符串,该字符串将在事件查看器向用户显示字符串之前与消息文件中的消息合并。

    备注
    Report 的这 4 个版本将消息报告给事件日志。提供这 4 个版本是为了让程序员可以使用最适合当前情况的版本。


    CNTEventLogSource::Deregister

    BOOL Deregister();

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    备注
    调用此函数关闭事件日志的句柄。如果您忘记自己关闭句柄,该函数将在析构函数中被调用。

    另请参阅
    Register


    CNTEventLogSource::Install

    static BOOL Install(LPCTSTR lpSourceName, LPCTSTR lpEventMessageFile, DWORD dwTypesSupported);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • lpSourceName -- 您要为其安装事件日志源的服务名称。
    • lpEventMessageFile -- 二进制文件的位置,其中可以找到 Message 表资源。这可以是一个标准的 exe 或 dll。
    • dwTypesSupported -- 指定支持类型的位掩码。它可以是以下值之一或多个
      • EVENTLOG_ERROR_TYPE
      • EVENTLOG_WARNING_TYPE
      • EVENTLOG_INFORMATION_TYPE
      • EVENTLOG_AUDIT_SUCCESS
      • EVENTLOG_AUDIT_FAILURE

    备注
    调用此函数以在注册表中设置必要的条目,以便事件查看器可以正确地找到用于显示在事件日志中的消息的消息文件。此函数作为 CNTService::Install() 的一部分被调用,并使用适当的值。

    另请参阅
    Uninstall


    CNTEventLogSource::Uninstall

    static BOOL Uninstall(LPCTSTR lpSourceName);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    备注
    调用此函数以从注册表中删除由 Install() 方法设置的条目。

    另请参阅
    Install



    CNTService

    CNTService 是一个类,它提供了一个 C++ 框架,您可以在其上开发自己的基于 MFC C++ 的服务。该类大量使用虚函数,您的服务类应该重写这些函数。

    此类提供的函数包括

    CNTService
    ~CNTService
    WriteProfileString
    WriteProfileInt
    WriteProfileBinary
    WriteProfileStringArray
    GetProfileString
    GetProfileInt
    GetProfileBinary
    GetProfileStringArray
    ParseCommandLine
    ProcessShellCommand
    ReportStatustoSCM
    RegisterCtrlHandler
    ServiceCtrlHandler
    ServiceMain
    OnStop
    OnPause
    OnContinue
    OnInterrogate
    OnShutdown
    OnUserDefinedRequest
    Run
    Install
    Uninstall
    Debug
    ShowHelp


    CNTService::CNTService

    CNTService(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName, DWORD dwControlsAccepted, LPCTSTR lpszDescription = NULL);

    参数

    • lpszServiceName -- 指向一个以 null 结尾的字符串,该字符串是服务的内部名称。
    • lpszDisplayName -- 指向一个以 null 结尾的字符串,该字符串将供用户界面程序用来识别此服务。
    • dwControlsAccepted -- 指定服务将接受和处理的控制代码。可以指定任何或所有以下标志以启用其他控制代码。
    • lpszDescription -- 服务的文本描述。这会显示在 Windows 2000 中新的服务 MMC 管理单元的“描述”列中。使用此值只是为了让管理员看到与您的服务关联的注释。默认值为 NULL,不会将描述插入注册表。
      含义
      SERVICE_ACCEPT_STOP 服务可以被停止。这启用了 SERVICE_CONTROL_STOP 值。
      SERVICE_ACCEPT_PAUSE_CONTINUE 服务可以被暂停和继续。这启用了 SERVICE_CONTROL_PAUSE 和 SERVICE_CONTROL_CONTINUE 值。
      SERVICE_ACCEPT_SHUTDOWN 服务会在系统关机时收到通知。这使得系统能够向服务发送 SERVICE_CONTROL_SHUTDOWN 值。ControlService 函数无法发送此控制代码。

    备注
    这是标准的构造函数,它根据传入的参数初始化许多内部变量。

    另请参阅
    ~CNTService


    CNTService::~CNTService

    ~CNTService();

    备注
    该类的标准析构函数。

    另请参阅
    CNTService


    CNTService::WriteProfileString

    BOOL WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。如果该节不存在,则会创建它。节的名称不区分大小写;字符串可以是任何大小写字母组合。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要写入该值的位置。如果该条目在指定的节中不存在,则会创建它。
    • lpszValue -- 指向要写入的字符串。如果此参数为 NULL,则删除由 lpszEntry 参数指定的条目。

    备注
    调用此成员函数以将指定的字符串写入注册表,服务应在此处存储其配置设置,即 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters


    CNTService::WriteProfileInt

    BOOL WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。如果该节不存在,则会创建它。节的名称不区分大小写;字符串可以是任何大小写字母组合。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要写入该值的位置。如果该条目在指定的节中不存在,则会创建它。
    • nValue -- 包含要写入的值。

    备注
    调用此成员函数以将指定的值写入注册表,服务应在此处存储其配置设置,即 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters


    CNTService::WriteProfileBinary

    BOOL WriteProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。如果该节不存在,则会创建它。节的名称不区分大小写;字符串可以是任何大小写字母组合。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要写入该值的位置。如果该条目在指定的节中不存在,则会创建它。
    • pData -- 指向要写入的二进制数据。
    • nBytes -- "pData" 的大小(以字节为单位)。

    备注
    调用此成员函数以将指定的二进制数据写入注册表,服务应在此处存储其配置设置,即 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName\Parameters


    CNTService::GetProfileString

    CString GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL);

    返回值
    返回值是注册表中的字符串,如果找不到字符串,则返回 lpszDefault。框架支持的最大字符串长度为 _MAX_PATH。如果 lpszDefault 为 NULL,则返回值为一个空字符串。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要写入该值的位置。此值不能为空。
    • lpszDefault -- 如果在注册表中找不到条目,则指向该条目的默认字符串值。

    备注
    调用此成员函数以从注册表中指定节内的条目检索关联的字符串。


    CNTService::GetProfileInt

    UINT GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault);

    返回值
    如果函数成功,则返回跟随指定条目的字符串的整数值。如果函数找不到条目,则返回值为 nDefault 参数的值。如果对应于指定条目的值不是整数,则返回值为 0。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要检索其值的条目。
    • nDefault -- 指定框架找不到条目时要返回的默认值。此值可以是 0 到 65,535 范围内的无符号值,或 -32,768 到 32,767 范围内的有符号值。

    备注
    调用此成员函数以从注册表中指定节内的条目检索整数值。

    此成员函数不区分大小写,因此 lpszSectionlpszEntry 参数中的字符串在大小写上可能不同。


    CNTService::GetProfileBinary

    BOOL GetProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPBYTE* ppData, UINT* pBytes);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要检索其二进制数据的条目。此值不能为空。
    • ppData -- 成功返回后,此指针将包含从注册表中读取的二进制数据。
    • nBytes -- 成功返回后,此指针将包含从注册表中读取的二进制数据的大小。

    备注
    调用此成员函数以设置注册表中指定节内条目关联的二进制值。在内部,数据以 REG_BINARY 值形式存储在注册表中。请注意,函数的调用者负责释放 ppData 中数据关联的内存。这可以通过以下方式实现: delete [] *ppData


    CNTService::GetProfileStringArray

    BOOL GetProfileStringArray(LPCTSTR lpszSection, LPCTSTR lpszEntry, CStringArray& array);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • lpszSection -- 指向一个以 null 结尾的字符串,该字符串指定了包含条目的节。
    • lpszEntry -- 指向一个以 null 结尾的字符串,该字符串包含要检索其二进制数据的条目。此值不能为空。
    • array -- 成功返回后,这将包含 CStringArray。

    备注
    调用此成员函数以从注册表中指定节内的条目检索字符串数组。该值以 MULTI_SZ 字符串形式存储在注册表中。


    CNTService::ParseCommandLine

    void ParseCommandLine(CNTServiceCommandLineInfo& rCmdInfo);

    参数

    • rCmdInfo -- 对 CNTServiceCommandLineInfo 对象的引用。

    备注
    调用此成员函数以解析命令行,并将参数一个接一个地发送到 CNTServiceCommandLineInfo::ParseParam()


    CNTService::ProcessShellCommand

    BOOL ProcessShellCommand(CNTServiceCommandLineInfo& rCmdInfo);

    返回值
    如果成功处理了 shell 命令,则返回 TRUE,否则返回 FALSE。

    参数

    • rCmdInfo -- 对 CNTServiceCommandLineInfo 对象的引用。

    备注
    此成员函数由您的 InitInstance()、main 或 wmain 调用,用于接受由 rCmdInfo 标识的 CNTServiceCommandLineInfo 对象传递的参数,并执行指示的操作。

    CNTServiceCommandLineInfo::m_nShellCommand 标识的 CNTServiceCommandLineInfo 对象的数据成员是以下枚举类型,它在 CNTServiceCommandLineInfo 类中定义。

    enum {
       RunAsService,
       InstallService, 
       UninstallService,
       DebugService, 
       ShowServiceHelp, 
    };
    


    CNTService::ReportStatusToSCM

    BOOL ReportStatusToSCM();
    BOOL ReportStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);

    返回值
    如果成功向 SCM 通知了此服务的状态,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • dwCurrentState -- 指示服务的当前状态。指定以下值之一
      含义
      SERVICE_STOPPED 服务未运行。
      SERVICE_START_PENDING 服务正在启动。
      SERVICE_STOP_PENDING 服务正在停止。
      SERVICE_RUNNING 服务正在运行。
      SERVICE_CONTINUE_PENDING 服务继续操作处于待定状态。
      SERVICE_PAUSE_PENDING 服务暂停操作处于待定状态。
      SERVICE_PAUSED 服务已暂停。
    • dwWin32ExitCode -- 指定服务在启动或停止时用于报告错误 Win32 错误代码。要返回服务特定的错误代码,服务必须将此值设置为 ERROR_SERVICE_SPECIFIC_ERROR,以指示 dwServiceSpecificExitCode 成员包含错误代码。服务应在运行时和正常终止时将此值设置为 NO_ERROR。
    • dwServiceSpecificExitCode -- 指定服务在启动或停止时发生错误时返回的服务特定错误代码。除非将 dwWin32ExitCode 成员设置为 ERROR_SERVICE_SPECIFIC_ERROR,否则将忽略此值。
    • dwCheckPoint -- 指定服务在长时间的启动、停止、暂停或继续操作期间定期递增的值,以报告其进度。例如,服务在启动过程中完成其初始化的每个步骤时,应递增此值。调用此操作的服务界面程序使用此值来跟踪服务在长时间操作期间的进度。当服务没有待处理的启动、停止、暂停或继续操作时,此值无效,应为零。
    • dwWaitHint -- 指定服务估计在调用 SetServiceStatus() 函数(带有递增的 dwCheckPoint 值或 dwCurrentState 的更改)之前,期望的待处理启动、停止、暂停或继续操作所需的时间(以毫秒为单位)。如果 dwWaitHint 指定的时间过去,并且 dwCheckPoint 未递增,或 dwCurrentState 未更改,则服务控制管理器或服务控制程序可以假定发生错误。

    备注
    这两个函数将服务的当前状态报告回服务控制管理器。第一个版本使用指定的参数,更新服务的内部状态后会将其报告给 SCM。第二个版本在向 SCM 报告时使用服务的现有状态。


    CNTService::RegisterCtrlHandler

    BOOL RegisterCtrlHandler();

    返回值
    如果此服务的 Control handler 成功注册,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    备注
    您应该在派生类的 ServiceMain 函数的开头调用此函数,以向 SCM 报告在发出对服务的请求时应回调哪个函数。在内部,当发出请求时,它将被路由到相应的虚函数。

    另请参阅
    ServiceCtrlHandler


    CNTService::ServiceCtrlHandler

    virtual void WINAPI ServiceCtrlHandler(DWORD dwControl);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • dwControl -- 指定请求的控制代码。此值可以是下表中列出的标准控制代码之一
      含义
      SERVICE_CONTROL_STOP 请求服务停止。
      SERVICE_CONTROL_PAUSE 请求服务暂停。
      SERVICE_CONTROL_CONTINUE 请求暂停的服务恢复。
      SERVICE_CONTROL_INTERROGATE 请求服务立即更新其当前状态信息到服务控制管理器。
      SERVICE_CONTROL_SHUTDOWN 请求服务执行清理任务,因为系统正在关闭。

      此值也可以是用户定义的控制代码,如下表所示

      含义
      范围 128 到 255。 服务定义与控制代码关联的操作。hService 句柄必须具有 SERVICE_USER_DEFINED_CONTROL 访问权限。

    备注
    SCM 会调用此函数,在内部它会委托给相应的虚函数。例如,如果收到 SERVICE_CONTROL_STOP 请求,则此函数将调用虚函数 OnStop()。此函数通常不需要在派生类中重写。请注意,此函数将在服务的 main 线程的上下文中调用,而不是在服务执行其主要工作(其 ServiceMain() 处理程序)的线程中调用。


    CNTService::ServiceMain

    virtual void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);

    返回值
    成功时返回 TRUE;否则返回 FALSE。

    参数

    • dwArgc -- 指定 lpszArgv 数组中的参数数量。
    • lpszArgv -- 指向指向以 null 结尾的参数字符串的指针数组。数组中的第一个参数是服务的名称,后续参数是调用 CScmService::Start() 函数来启动服务的进程传递给服务的任何字符串。

    备注
    在派生类中,您负责为您的服务编写自己的 ServiceMain() 函数。

    当服务控制程序请求运行新服务时,SCM 会启动该服务并将启动请求发送到控制调度程序。控制调度程序会创建一个新线程来执行该服务的 ServiceMain() 函数。

    ServiceMain() 函数应执行以下任务

    1. 立即调用 RegisterServiceCtrlHandler() 函数以注册一个处理函数来处理服务的控制请求。
    2. 执行初始化。如果初始化代码的执行时间预计很短(不到一秒),则可以直接在 ServiceMain() 中执行初始化。
    3. 初始化完成后,调用 SetServiceStatus(),在 SERVICE_STATUS 结构中指定 SERVICE_RUNNING 状态。
    4. 执行服务任务,或者,如果没有待处理的任务,则返回。服务的任何状态更改都应调用 ReportStatusToSCM 来报告新状态信息。
    5. 如果服务在初始化或运行时发生错误,服务应调用,指定 SERVICE_STOP_PENDING 状态,如果清理工作将是漫长的。一旦清理完成,从最后一个终止线程调用 ReportStatusToSCM(),在 SERVICE_STATUS 结构中指定 SERVICE_STOPPED。确保设置 SERVICE_STATUS 结构中的 dwServiceSpecificExitCodedwWin32ExitCode 成员以标识错误。


    CNTService::OnStop

    virtual void OnStop();

    备注
    每当 SCM 收到 SERVICE_CONTROL_STOP 请求时,都会调用此函数。您的派生类应执行任何必要的操作以使您的服务停止。


    CNTService::OnPause

    virtual void OnPause();

    备注
    每当 SCM 收到 SERVICE_CONTROL_PAUSE 请求时,都会调用此函数。您的派生类应执行任何必要的操作以使您的服务暂停。


    CNTService::OnContinue

    virtual void OnContinue();

    备注
    每当 SCM 收到 SERVICE_CONTROL_CONTINUE 请求时,都会调用此函数。您的派生类应执行任何必要的操作以使您的服务继续。


    CNTService::OnInterrogate

    virtual void OnInterrogate();

    备注
    每当 SCM 收到 SERVICE_CONTROL_INTERROGATE 请求时,都会调用此函数。默认实现只是调用 ReportStatusToSCM 来通知 SCM。


    CNTService::OnShutdown

    virtual void OnShutdown();

    备注
    每当 SCM 收到 SERVICE_CONTROL_SHUTDOWN 时,都会调用此函数。您的派生类应执行任何必要的操作以使您的服务关闭。


    CNTService::OnUserDefinedRequest

    virtual void OnUserDefinedRequest(DWORD dwControl);

    备注
    每当 SCM 收到用户定义的请求时,都会调用此函数。您的派生类应执行适合其服务的操作。在提供的示例服务中,它只是更改服务发出的蜂鸣声频率。


    CNTService::Run

    virtual BOOL Run();

    备注
    调用此函数将使服务开始运行。在内部,它将设置适当的 SERVICE_TABLE_ENTRY 数组并调用 StartServiceCtrlDispatcher 来启动服务。您通常会在 main、wmain 或 InitInstance 中调用此函数。如果您正在使用 CNTServiceCNTServiceCommandLineInfo 类以及 ParseCommandLine()ProcessShellCommand() 成员函数,则无需调用此函数。


    CNTService::Install

    virtual BOOL Install();

    备注
    这将安装一个服务。在内部,它将调用 SCM API 以将此服务设置为按需服务,无依赖项。在 CNTService 的未来版本中,将提供虚函数以允许在此区域进行更多自定义。它还将安装服务,以便它可以向事件日志报告事件,并允许事件查看器使用服务的友好名称进行过滤。如果命令行为 "-install",则 CNTServiceCommandLineInfo 将在此函数中内部调用此函数。


    CNTService::Uninstall

    virtual BOOL Uninstall();

    备注
    这是 Install 的对应函数,它将从 SCM 数据库中删除该服务并删除其事件日志注册表项。请注意,一旦完成此操作,事件查看器将无法正确显示该服务在安装期间生成的任何消息。如果命令行为 "-uninstall" 或 "-remove",则 CNTServiceCommandLineInfo 将在此函数中内部调用此函数。


    CNTService::Debug

    virtual void Debug();

    备注
    这将在不与 SCM 交互的情况下运行服务,实际上是“调试”模式。这有助于在测试应用程序时,因为它会阻止 SCM 在调试服务时超时。在内部,此函数将仅调用您的类的 ServiceMain 函数。请记住,在这种情况下,您的服务代码将在与主线程相同的线程中运行,因此它可能会掩盖仅在代码作为实际服务执行时才会出现的问题。如果命令行为 "-debug",则 CNTServiceCommandLineInfo 将在此函数中内部调用此函数。


    CNTService::ShowHelp

    virtual void ShowHelp();

    备注
    如果命令行为 "-help" 或 "-?",则 CNTServiceCommandLineInfo 将在此函数中内部调用此函数。您需要打印一些消息到控制台(如果您正在开发控制台模式服务)或显示一个有用的窗口(如果它是 GUI 应用程序)。示例服务仅使用 AfxMessageBox() 显示一条消息,因为它使用的是 GUI 子系统开发的。



    CNTScmService

    CNTScmService 是一个封装了服务控制管理器返回的服务(实际上是 SC_HANDLE)的类。CNTScmService 的实例通常是通过调用 CNTServiceControlManager::Open 来获取的。获取后,该类允许您控制服务、更改其配置并查询服务的状态。

    此类提供的函数包括

    CNTScmService
    ~CNTScmService
    Close
    operator SC_HANDLE
    Attach
    Detach
    ChangeConfig
    Control
    停止
    Pause
    Continue
    Interrogate
    Start
    AcceptStop
    AcceptPauseContinue
    AcceptShutdown
    QueryStatus
    QueryConfig
    Create
    删除
    EnumDependents
    QueryObjectSecurity
    SetObjectSecurity


    CNTScmService::CNTScmService

    CNTScmService();

    备注
    这是默认构造函数,它会将所有内部变量初始化为安全状态。

    另请参阅
    ~CNTScmService()


    CNTScmService::~CNTScmService

    ~CNTScmService();

    备注
    这是该类的标准析构函数。它会在内部调用 Close() 以确保关闭此实例打开的任何句柄。

    另请参阅
    CNTScmService(), Close()


    CNTScmService::Close

    void Close();

    备注
    这会释放 SC_HANDLE,通过内部调用 CloseServiceHandle 来实现,该函数由本类封装。


    CNTScmService::operator SC_HANDLE

    operator SC_HANDLE() const;

    返回值
    代表此类底层 SDK 服务句柄。

    备注
    此函数公开了 CNTScmService 类包装的底层句柄。此函数用于与直接使用句柄的旧代码集成。


    CNTScmService::Attach

    BOOL Attach(SC_HANDLE hService);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • hService -- 从 SCM API 的 SDK 调用返回的 SDK 服务句柄

    备注
    使用此成员函数将现有 SDK 句柄附加到 CNTScmService。

    另请参阅
    Detach.


    CNTScmService::Detach

    SC_HANDLE Detach();

    返回值
    SDK 服务句柄。

    备注
    调用此函数以将 m_hService 与 CNTScmService 对象分离,并将 m_hService 设置为 NULL。

    另请参阅
    Attach.


    CNTScmService::ChangeConfig

    BOOL ChangeConfig(DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword, LPCTSTR lpDisplayName) const;

    备注
    这是对 SDK 调用 ChangeServiceConfig() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTScmService::Control

    BOOL Control(DWORD dwControl);

    参数

    • dwControl -- 指定要发送到此服务的控制代码。此值可以是下表中列出的标准控制代码之一
      含义
      SERVICE_CONTROL_STOP 请求服务停止。
      SERVICE_CONTROL_PAUSE 请求服务暂停。
      SERVICE_CONTROL_CONTINUE 请求暂停的服务恢复。
      SERVICE_CONTROL_INTERROGATE 请求服务立即更新其当前状态信息到服务控制管理器。
      SERVICE_CONTROL_SHUTDOWN 请求服务执行清理任务,因为系统正在关闭。

      此值也可以是用户定义的控制代码,如下表所示

      含义
      范围 128 到 255。 服务定义与控制代码关联的操作。hService 句柄必须具有 SERVICE_USER_DEFINED_CONTROL 访问权限。

    备注
    这是对 SDK 调用 ControlService() SDK Call 的简单包装。


    CNTScmService::Stop

    BOOL Stop() const;

    备注
    这是通过将参数 SERVICE_CONTROL_STOP 传递给 Control() 的简单包装。


    CNTScmService::Pause

    BOOL Pause() const;

    备注
    这是通过将参数 SERVICE_CONTROL_PAUSE 传递给 Control() 的简单包装。


    CNTScmService::Continue

    BOOL Continue() const;

    备注
    这是通过将参数 SERVICE_CONTROL_CONTINUE 传递给 Control() 的简单包装。


    CNTScmService::Interrogate

    BOOL Interrogate() const;

    备注
    这是通过将参数 SERVICE_CONTROL_INTERROGATE 传递给 Control() 的简单包装。


    CNTScmService::Start

    BOOL Start(DWORD dwNumServiceArgs, LPCTSTR* lpServiceArgVectors) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • dwNumServiceArgs -- 指定 lpServiceArgVectors 数组中参数字符串的数量。如果 lpServiceArgVectors 为 NULL,则此参数可以为零。
    • lpServiceArgVectors -- 指向指向传递给服务的以 null 结尾的参数字符串的指针数组。驱动程序服务不接收这些参数。如果未向要启动的服务传递参数,则此参数可以为 NULL。

    备注
    使用指定参数启动此服务。


    CNTScmService::AcceptStop

    BOOL AcceptStop(BOOL& bStop);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • bStop -- 在此函数成功返回后,bStop 将指示此服务是否可以被停止。

    备注
    查询此服务以确定此服务当前是否可以被停止。


    CNTScmService::AcceptPauseContinue

    BOOL AcceptPauseContinue(BOOL& bPauseContinue);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • bPauseContinue -- 在此函数成功返回后,bPauseContinue 将指示此服务是否可以被暂停和继续。

    备注
    查询此服务以确定此服务当前是否可以被暂停/继续。


    CNTScmService::AcceptShutdown

    BOOL AcceptShutdown(BOOL& bShutdown);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • bShutdown -- 在此函数成功返回后,bShutdown 将指示此服务是否处理关机请求。

    备注
    查询此服务以确定此服务是否处理关机请求。


    CNTScmService::QueryStatus

    BOOL QueryStatus(LPSERVICE_STATUS lpServiceStatus) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • lpServiceStatus -- 在此函数成功返回后,lpServiceStatus 将包含此服务的当前状态。

    备注
    查询此服务的当前状态。


    CNTScmService::QueryConfig

    BOOL QueryConfig(LPQUERY_SERVICE_CONFIG& lpServiceConfig) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • lpServiceConfig -- 在此函数成功返回后,lpServiceConfig 将包含此服务的当前配置。

    备注
    查询此服务的当前配置。请注意,由于 QUERY_SERVICE_CONFIG 是一个变长结构,此函数将在内部分配 lpServiceConfig 所需的内存,客户端负责删除此结构。这可以通过以下方式完成:

    LPQUERY_SERVICE_CONFIG lpConfig = NULL;
    service.QueryConfig(lpConfig);
    delete [] (BYTE*) lpConfig;
    


    CNTScmService::Create

    BOOL Create(CNTServiceControlManager& Manager, LPCTSTR lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword);

    备注
    这是对同名 SDK 调用 CreateService() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTScmService::Delete

    BOOL Delete() const;

    备注
    这是对 SDK 调用 DeleteService() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTScmService::EnumDependents

    BOOL EnumDependents(DWORD dwServiceState, DWORD dwUserData, ENUM_SERVICES_PROC lpEnumServicesFunc) const;

    参数

    • dwServiceState -- 指定要枚举的服务,基于它们运行的状态。它必须是以下值之一或两者
      含义
      SERVICE_ACTIVE 枚举处于以下状态的服务:SERVICE_START_PENDING、SERVICE_STOP_PENDING、SERVICE_RUNNING、SERVICE_CONTINUE_PENDING、SERVICE_PAUSE_PENDING 和 SERVICE_PAUSED。
      SERVICE_INACTIVE 枚举处于 SERVICE_STOPPED 状态的服务。
      SERVICE_STATE_ALL 组合以下状态:SERVICE_ACTIVE 和 SERVICE_INACTIVE。
    • dwUserData -- 您想发送到回调函数的任何用户定义的 DWORD。
    • lpEnumServicesFunc -- 指向用于枚举依赖服务的回调函数的指针。

    备注
    此函数允许您枚举此服务依赖的服务。在内部,它调用 EnumDependentServices() 并为每个服务调用回调函数。回调函数的格式为

    BOOL CALLBACK ENUM_SERVICES_PROC(DWORD dwData, ENUM_SERVICE_STATUS& ServiceStatus);

    • dwData -- 这是传递给 Enumeration 函数的值。
    • ServiceStatus -- 包含有关已枚举服务的信息。有关更多详细信息,请参阅 SDK 文档。

    从函数返回 TRUE 以继续枚举,返回 FALSE 以停止枚举。


    CNTScmService::QueryObjectSecurity

    BOOL QueryObjectSecurity(SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR& lpSecurityDescriptor) const;

    备注
    这是对 SDK 调用 QueryServiceObjectSecurity() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTScmService::SetObjectSecurity

    BOOL SetObjectSecurity(SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR& lpSecurityDescriptor) const;

    备注
    这是对 SDK 调用 SetServiceObjectSecurity() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。请注意,由于 PSECURITY_DESCRIPTOR 是一个变长结构,此函数将在内部分配 lpSecurityDescriptor 所需的内存,客户端负责删除此结构。这可以通过以下方式完成:

    PSECURITY_DESCRIPTOR lpDescriptor = NULL;
    service.QueryObjectSecurity(whatever, lpDescriptor);
    delete [] (BYTE*) lpDescriptor;
    



    CNTServiceControlManager

    CNTServiceControlManager 是一个封装了与某些机器上的服务控制管理器 (SCM) 的连接的类。提供的功能包括枚举、数据库锁定和服务访问。

    此类提供的函数包括

    CNTServiceControlManager
    ~CNTServiceControlManager
    operator HANDLE
    Attach
    Detach
    打开
    Close
    QueryLockStatus
    EnumServices
    OpenService
    锁定
    Unlock


    CNTServiceControlManager::CNTServiceControlManager

    CNTServiceControlManager();

    备注
    这是默认构造函数,它会将所有内部变量初始化为安全状态。

    另请参阅
    ~CNTServiceControlManager().


    CNTServiceControlManager::~CNTServiceControlManager

    ~CNTServiceControlManager();

    备注
    这是该类的标准析构函数。它会在内部调用 Close() 以确保关闭此实例打开的任何句柄。

    另请参阅
    CNTServiceControlManager(), Close()


    CNTServiceControlManager::operator HANDLE

    operator SC_HANDLE() const;

    返回值
    代表此类底层 SDK 服务句柄。

    备注
    此函数公开了 CNTServiceControlManager 类包装的底层句柄。此函数用于与直接使用句柄的旧代码集成。


    CNTServiceControlManager::Attach

    BOOL Attach(SC_HANDLE hSCM);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • hSCM -- 从 SCM API 的 SDK 调用返回的 SDK 服务控制管理器句柄。

    备注
    使用此成员函数将现有 SDK 句柄附加到 CNTServiceControlManager

    另请参阅
    Detach


    CNTServiceControlManager::Detach

    SC_HANDLE Detach();

    返回值
    SDK 服务控制管理器句柄。

    备注
    调用此函数以将 m_hSCMCNTServiceControlManager 对象分离,并将 m_hSCM 设置为 NULL。

    另请参阅
    Attach


    CNTServiceControlManager::Open

    BOOL Open(LPCTSTR pszMachineName, DWORD dwDesiredAccess);

    备注
    这是对 SDK 调用 OpenSCManager() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTServiceControlManager::Close

    void Close();

    备注
    这会释放 SC_HANDLE,通过内部调用 CloseServiceHandle() 来实现,该函数由本类封装。


    CNTServiceControlManager::Close

    void Close();

    备注
    这会释放 SC_HANDLE,通过内部调用 CloseServiceHandle() 来实现,该函数由本类封装。


    CNTServiceControlManager::QueryLockStatus

    BOOL QueryLockStatus(LPQUERY_SERVICE_LOCK_STATUS& lpLockStatus) const;

    备注
    这是对 SDK 调用 QueryServiceLockStatus() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。请注意,由于 LPQUERY_SERVICE_LOCK_STATUS 是一个变长结构,此函数将在内部分配 lpLockStatus 所需的内存,客户端负责删除此结构。这可以通过以下方式完成:

    LPQUERY_SERVICE_LOCK_STATUS lpLockStatus = NULL;
    scm.QueryLockStatus(lpLockStatus);
    delete [] (BYTE*) lpLockStatus;
    


    CNTServiceControlManager::EnumServices

    BOOL EnumServices(DWORD dwServiceType, DWORD dwServiceState, DWORD dwUserData, ENUM_SERVICES_PROC lpEnumServicesFunc) const;

    参数

    • dwServiceType -- 指定要枚举的服务类型。它必须是以下值之一或两者
      含义
      SERVICE_WIN32 枚举类型为 SERVICE_WIN32_OWN_PROCESS 和 SERVICE_WIN32_SHARE_PROCESS 的服务。
      SERVICE_DRIVER 枚举类型为 SERVICE_KERNEL_DRIVER 和 SERVICE_FILE_SYSTEM_DRIVER 的服务。
    • dwServiceState -- 指定要枚举的服务,基于它们运行的状态。它必须是以下值之一或两者
      含义
      SERVICE_ACTIVE 枚举处于以下状态的服务:SERVICE_START_PENDING、SERVICE_STOP_PENDING、SERVICE_RUNNING、SERVICE_CONTINUE_PENDING、SERVICE_PAUSE_PENDING 和 SERVICE_PAUSED。
      SERVICE_INACTIVE 枚举处于 SERVICE_STOPPED 状态的服务。
      SERVICE_STATE_ALL 组合以下状态:SERVICE_ACTIVE 和 SERVICE_INACTIVE。
    • dwUserData -- 您想发送到回调函数的任何用户定义的 DWORD。
    • lpEnumServicesFunc -- 指向用于枚举依赖服务的回调函数的指针。

    备注
    此函数允许您枚举 SCM 中的服务。在内部,它调用 EnumServicesStatus() 并为每个服务调用回调函数。回调函数的格式为

    typedef BOOL CALLBACK ENUM_SERVICES_PROC(DWORD dwData, ENUM_SERVICE_STATUS& ServiceStatus);

    • dwData -- 这是传递给 Enumeration 函数的值。
    • ServiceStatus -- 包含有关已枚举服务的信息。有关更多详细信息,请参阅 SDK 文档。

    从函数返回 TRUE 以继续枚举,返回 FALSE 以停止枚举。


    CNTServiceControlManager::OpenService

    BOOL OpenService(LPCTSTR lpServiceName, DWORD dwDesiredAccess, CNTScmService& service) const;

    备注
    这是对同名 SDK 调用 OpenService() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTServiceControlManager::Lock

    BOOL Lock();

    备注
    这是对 SDK 调用 LockServiceDatabase() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTServiceControlManager::Unlock

    BOOL Unlock();

    备注
    这是对 SDK 调用 UnlockServiceDatabase() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。



    CEventLogRecord

    CEventLogRecord 是一个 C++ 包装类,用于 SDK 中提供的 EVENTLOGRECORD 结构。对于任何曾使用原始 SDK 调用使用此类的用户来说,您将欣赏该类提供的更便捷的访问方式。

    此类提供的函数和成员包括

    CEventLogRecord
    operator=
    m_dwRecordNumber
    m_TimeGenerated
    m_TimeWritten
    m_dwEventID
    m_wEventTypes
    m_wEventCategory
    m_UserSID
    m_Strings
    m_Data
    m_sSourceName
    m_sComputerName


    CEventLogRecord::CEventLogRecord

    CEventLogRecord();
    CEventLogRecord(const CEventLogRecord& record);
    CEventLogRecord(const EVENTLOGRECORD* pRecord);

    参数

    • record -- 一个现有的 CEventLogRecord。
    • pRecord -- 一个现有的 SDK EVENTLOGRECORD 结构。


    CEventLogRecord::operator=

    CEventLogRecord& operator=(const CEventLogRecord& record);

    备注
    标准拷贝构造函数。


    CEventLogRecord::m_dwRecordNumber

    DWORD m_dwRecordNumber;

    备注
    包含此事件日志条目的记录号。


    CEventLogRecord::m_TimeGenerated

    CTime m_TimeGenerated;

    备注
    此条目提交时间的 CTime 表示。


    CEventLogRecord::m_TimeWritten

    CTime m_TimeWritten;

    备注
    此条目写入事件日志时间的 CTime 表示。


    CEventLogRecord::m_dwEventID

    DWORD m_dwEventID;

    备注
    指定事件。这对于生成事件日志条目的源是特定的,并与 SourceName 一起用于标识消息文件中的消息,该消息在查看日志时会显示给用户。


    CEventLogRecord::m_wEventTypes

    WORD m_wEventType;

    备注
    指定事件的类型。此成员可以是以下值之一

    含义
    EVENTLOG_ERROR_TYPE 错误事件
    EVENTLOG_WARNING_TYPE 警告事件
    EVENTLOG_INFORMATION_TYPE 信息事件
    EVENTLOG_AUDIT_SUCCESS 成功审计事件
    EVENTLOG_AUDIT_FAILURE 失败审计事件


    CEventLogRecord::m_UserSID

    CByteArray m_UserSID;

    备注
    在记录此事件时处于活动状态的用户的安全标识符的 CByteArray 表示。


    CEventLogRecord::m_Strings

    CStringArray m_Strings;

    备注
    字符串的 CStringArray 表示,这些字符串在显示给用户之前会与消息合并。


    CEventLogRecord::m_Data

    CByteArray m_Data;

    备注
    此事件记录中事件特定信息的 CByteArray 表示。


    CEventLogRecord::m_sSourceName

    CString m_sSourceName;

    备注
    包含指定生成事件的源(应用程序、服务、驱动程序、子系统)名称的字符串。


    CEventLogRecord::m_sComputerName

    CString m_sComputerName;

    备注
    包含指定生成此事件的计算机名称的字符串。



    CNTEventLog

    CNTEventLog 是一个 C++ 包装类,用于访问 NT 事件日志。您可以将其视为 Event Log API 的客户端。

    此类提供的函数包括

    CNTEventLog
    ~CNTEventLog
    operator HANDLE
    Attach
    Detach
    打开
    OpenBackup
    OpenApplication
    OpenSystem
    OpenSecurity
    Close
    备份
    Clear
    GetNumberOfRecords
    GetOldestRecord
    NotifyChange
    ReadNext
    ReadPrev


    CNTEventLog::CNTEventLog

    CNTEventLog();

    备注
    这是默认构造函数,它会将所有内部变量初始化为安全状态。

    另请参阅
    ~CNTEventLog().


    CNTEventLog::~CNTEventLog

    ~CNTEventLog();

    备注
    这是该类的标准析构函数。它会在内部调用 Close() 以确保关闭此实例打开的任何句柄。

    另请参阅
    CNTEventLog(), Close()


    CNTEventLog::operator HANDLE

    operator HANDLE() const;

    返回值
    代表此类底层 SDK 事件日志句柄。

    备注
    此函数公开了 CNTEventLog 类包装的底层句柄。此函数用于与直接使用句柄的旧代码集成。


    CNTEventLog::Attach

    BOOL Attach(HANDLE hEventLog);

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • hEventLog -- 从 Event log API 的 SDK 调用返回的 SDK 事件日志句柄。

    备注
    使用此成员函数将现有 SDK 句柄附加到 CNTEventLog

    另请参阅
    Detach


    CNTEventLog::Detach

    HANDLE Detach();

    返回值
    SDK 事件日志句柄。

    备注
    调用此函数以将 m_hEventLogCNTEventLog 对象分离,并将 m_hEventLog 设置为 NULL。

    另请参阅
    Attach


    CNTEventLog::Open

    BOOL Open(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName);

    备注
    这是对 SDK 调用 OpenEventLog() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::OpenBackup

    BOOL OpenBackup(LPCTSTR lpUNCServerName, LPCTSTR lpFileName);

    备注
    这是对 SDK 调用 OpenBackupEventLog() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::OpenApplication

    BOOL OpenApplication(LPCTSTR lpUNCServerName);

    备注
    这是一个打开指定计算机上“应用程序”事件日志的示例包装器,它在内部调用 Open() 并使用适当的字符串“Application”。


    CNTEventLog::OpenSystem

    BOOL OpenSystem(LPCTSTR lpUNCServerName);

    备注
    这是一个打开指定计算机上“系统”事件日志的示例包装器,它在内部调用 Open() 并使用适当的字符串“System”。


    CNTEventLog::OpenSecurity

    BOOL OpenSecurity(LPCTSTR lpUNCServerName);

    备注
    这是一个打开指定计算机上“安全”事件日志的示例包装器,它在内部调用 Open() 并使用适当的字符串“Security”。


    CNTEventLog::Close

    BOOL Close();

    备注
    这会释放 HANDLE,通过内部调用 CloseEventLog 来实现,该函数由本类封装。


    CNTEventLog::Backup

    BOOL Backup(LPCTSTR lpBackupFileName) const;

    备注
    这是对 SDK 调用 BackupeventLog() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::Clear

    BOOL Clear(LPCTSTR lpBackupFileName) const;

    备注
    这是对 SDK 调用 ClearEventLog() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::GetNumberOfRecords

    BOOL GetNumberOfRecords(DWORD& dwNumberOfRecords) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • dwNumberOfRecords -- 成功返回后,此变量将包含事件日志中的记录数。

    备注
    这是对 SDK 调用 GetNumberOfEventLogRecords() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::GetOldestRecord

    BOOL GetOldestRecord(DWORD& dwOldestRecord) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • dwOldestRecord -- 成功返回后,此变量将包含事件日志中最旧记录的记录号。

    备注
    这是对 SDK 调用 GetOldestEventLogRecord() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::NotifyChange

    BOOL NotifyChange(HANDLE hEvent) const;

    备注
    这是对 SDK 调用 NotifyChangeEventLog() 的简单包装。有关此函数的完整详细信息,请参阅 SDK。


    CNTEventLog::ReadNext

    BOOL ReadNext(CEventLogRecord& record) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • record -- 成功返回后,此变量将包含事件日志中的下一条记录。

    备注
    从事件日志中按时间顺序向前读取下一条记录。当此函数成功返回时,读取位置会增加一,为下一次读取做好准备。


    CNTEventLog::ReadPrev

    BOOL ReadPrev(CEventLogRecord& record) const;

    返回值
    如果函数成功,则返回 TRUE,否则返回 FALSE。要获取扩展错误信息,请调用 GetLastError()

    参数

    • record -- 成功返回后,此变量将包含事件日志中的上一条记录。

    备注
    从事件日志中按时间顺序向后读取下一条记录。当此函数成功返回时,读取位置会减一,为下一次读取做好准备。



    计划增强功能

    • 检查所有类,以确定每个成员函数需要哪些参数,并可以设置默认值。
    • 如果您有任何改进建议,请告知我,以便我将其纳入下一版本。


    参考文献

    • Nigel Thompson 在 MSDN 上的文章《Creating a Simple Windows NT Service in C++》。
    • Sam Blackburn 开发的 Win32 Foundation Classes
    • Platform SDK 中有许多文章,任何考虑编写服务的人都应该阅读。涵盖的领域包括:写入 NT 事件日志、从事件日志读取、简单 C/SDK 风格服务的结构、服务控制管理器 (SCM)、向 SCM 报告状态、使用消息编译器 (MC) 等等。


    联系作者

    PJ Naughter
    电子邮件:pjn@indigo.ie
    网站:http://www.naughter.com
    2000 年 1 月 24 日


    © . All rights reserved.