CNTService v1.06 - NT 服务框架






4.97/5 (16投票s)
2000 年 3 月 4 日

309653

4509
用于在 MFC 中开发 NT 服务的类框架。
引言
欢迎使用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 - hEventSource -- 从
- 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 个版本是为了让程序员可以使用最适合当前情况的版本。 - wType -- 指定要记录的事件类型。此参数可以是以下值之一
- 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 范围内的有符号值。
备注
调用此成员函数以从注册表中指定节内的条目检索整数值。此成员函数不区分大小写,因此 lpszSection 和 lpszEntry 参数中的字符串在大小写上可能不同。
- 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()
。 - rCmdInfo -- 对
- 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, };
- rCmdInfo -- 对
- 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 报告时使用服务的现有状态。 - dwCurrentState -- 指示服务的当前状态。指定以下值之一
- 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()
处理程序)的线程中调用。 - dwControl -- 指定请求的控制代码。此值可以是下表中列出的标准控制代码之一
- CNTService::ServiceMain
- virtual void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);
返回值
成功时返回 TRUE;否则返回 FALSE。参数
- dwArgc -- 指定 lpszArgv 数组中的参数数量。
- lpszArgv -- 指向指向以 null 结尾的参数字符串的指针数组。数组中的第一个参数是服务的名称,后续参数是调用 CScmService::Start() 函数来启动服务的进程传递给服务的任何字符串。
备注
在派生类中,您负责为您的服务编写自己的ServiceMain()
函数。当服务控制程序请求运行新服务时,SCM 会启动该服务并将启动请求发送到控制调度程序。控制调度程序会创建一个新线程来执行该服务的
ServiceMain()
函数。ServiceMain()
函数应执行以下任务- 立即调用 RegisterServiceCtrlHandler() 函数以注册一个处理函数来处理服务的控制请求。
- 执行初始化。如果初始化代码的执行时间预计很短(不到一秒),则可以直接在
ServiceMain()
中执行初始化。 - 初始化完成后,调用
SetServiceStatus()
,在SERVICE_STATUS
结构中指定 SERVICE_RUNNING 状态。 - 执行服务任务,或者,如果没有待处理的任务,则返回。服务的任何状态更改都应调用 ReportStatusToSCM 来报告新状态信息。
- 如果服务在初始化或运行时发生错误,服务应调用,指定 SERVICE_STOP_PENDING 状态,如果清理工作将是漫长的。一旦清理完成,从最后一个终止线程调用 ReportStatusToSCM(),在
SERVICE_STATUS
结构中指定 SERVICE_STOPPED。确保设置SERVICE_STATUS
结构中的 dwServiceSpecificExitCode 和 dwWin32ExitCode 成员以标识错误。
- 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 中调用此函数。如果您正在使用CNTService
的 CNTServiceCommandLineInfo 类以及 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 的简单包装。 - dwControl -- 指定要发送到此服务的控制代码。此值可以是下表中列出的标准控制代码之一
- 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 以停止枚举。
- dwServiceState -- 指定要枚举的服务,基于它们运行的状态。它必须是以下值之一或两者
- 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_hSCM 与CNTServiceControlManager
对象分离,并将 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 以停止枚举。
- dwServiceType -- 指定要枚举的服务类型。它必须是以下值之一或两者
- 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_hEventLog 与CNTEventLog
对象分离,并将 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 日