[Win32] SCManager 服务控制管理器API(2)

来源:互联网 发布:linux重启后ping不通 编辑:程序博客网 时间:2024/04/29 05:14
本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/47808805
在上一篇博文“[Win32] SCManager 服务控制管理器API(1)”中(地址:http://blog.csdn.net/zuishikonghuan/article/details/47803033),讲到了打开服务控制管理器、创建服务、打开服务、删除服务、获取服务状态、启动服务、发送控制码,这一篇继续。

9。EnumServicesStatus 枚举服务

BOOL WINAPI EnumServicesStatus(  _In_        SC_HANDLE             hSCManager,  _In_        DWORD                 dwServiceType,  _In_        DWORD                 dwServiceState,  _Out_opt_   LPENUM_SERVICE_STATUS lpServices,  _In_        DWORD                 cbBufSize,  _Out_       LPDWORD               pcbBytesNeeded,  _Out_       LPDWORD               lpServicesReturned,  _Inout_opt_ LPDWORD               lpResumeHandle);

hSCManager:服务控制管理器句柄。此句柄是OpenSCManager函数返回的,并且必须具有 SC_MANAGER_ENUMERATE_SERVICE 访问权限。

dwServiceType:要枚举的服务类型。

SERVICE_DRIVER:SERVICE_KERNEL_DRIVER 和 SERVICE_FILE_SYSTEM_DRIVER。SERVICE_FILE_SYSTEM_DRIVER:文件系统驱动程序服务。SERVICE_KERNEL_DRIVER:驱动程序服务。SERVICE_WIN32:SERVICE_WIN32_OWN_PROCESS 和 SERVICE_WIN32_SHARE_PROCESS。SERVICE_WIN32_OWN_PROCESS:在他们自己的进程中运行的服务。SERVICE_WIN32_SHARE_PROCESS:与一个或多个其他服务共享一个进程的服务。
一般为SERVICE_WIN32

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。

lpServices:指向包含数组的 ENUM_SERVICE_STATUS 结构,它接收名称服务数据库中的每个服务的状态信息的缓冲区的指针。缓冲区必须足够大以容纳结构,再加上他们的成员所指向的字符串。此数组的最大大小为 256 K 字节。若要确定所需的大小,请为此参数与 cbBufSize 参数置 0。该函数将失败,时出错将返回 ERROR_INSUFFICIENT_BUFFER。PcbBytesNeeded 参数将收到所需的大小。

ENUM_SERVICE_STATUS 结构:

typedef struct _ENUM_SERVICE_STATUS {  LPTSTR         lpServiceName;  LPTSTR         lpDisplayName;  SERVICE_STATUS ServiceStatus;} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

lpServiceName:服务名称

lpDisplayName:显示名称

ServiceStatus:服务状态

SERVICE_STATUS结构见 上一篇 和[Win32] 服务程序开发(1)基本概念和服务程序的框架

cbBufSize:以字节为单位所指向的缓冲区的大小

pcbBytesNeeded:如果缓冲区太小,指向接收的需要返回剩余的服务条目的字节数的变量的指针。

lpServicesReturned:指向一个变量来接收服务项数返回的指针。

lpResumeHandle:一个指针指向的变量的输入,指定枚举的起始点。你必须第一次调用此函数设置此值为零。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

10。QueryServiceConfig 获取服务配置参数

BOOL WINAPI QueryServiceConfig(  _In_      SC_HANDLE              hService,  _Out_opt_ LPQUERY_SERVICE_CONFIG lpServiceConfig,  _In_      DWORD                  cbBufSize,  _Out_     LPDWORD                pcbBytesNeeded);

hService:务的句柄。此句柄是OpenService 或 CreateService函数返回的,并且它必须具有 SERVICE_QUERY_CONFIG 访问权限。

lpServiceConfig:指向接收服务配置信息的缓冲区的指针。数据的格式是一个 QUERY_SERVICE_CONFIG 结构。

QUERY_SERVICE_CONFIG结构:

typedef struct _QUERY_SERVICE_CONFIG {  DWORD  dwServiceType;  DWORD  dwStartType;  DWORD  dwErrorControl;  LPTSTR lpBinaryPathName;  LPTSTR lpLoadOrderGroup;  DWORD  dwTagId;  LPTSTR lpDependencies;  LPTSTR lpServiceStartName;  LPTSTR lpDisplayName;} QUERY_SERVICE_CONFIG, *LPQUERY_SERVICE_CONFIG;

dwServiceType:见上一篇中对”Createservice“的介绍。(传送门)

dwStartType:见上一篇中对”Createservice“的介绍。(传送门)

dwErrorControl:见上一篇中对”Createservice“的介绍。(传送门)

lpBinaryPathName:见上一篇中对”Createservice“的介绍。(传送门)

lpLoadOrderGroup:见上一篇中对”Createservice“的介绍。(传送门)

dwTagId:见上一篇中对”Createservice“的介绍。(传送门)

lpDependencies:见上一篇中对”Createservice“的介绍。(传送门)

lpServiceStartName:如果服务类型为 SERVICE_WIN32_OWN_PROCESS 或 SERVICE_WIN32_SHARE_PROCESS,此成员是帐户的服务进程将登录作为运行时的名称。此名称可以是Domain\UserName。如果该帐户属于内置域,名称可以是.\UserName。如果进程运行在本地系统帐户下,名称也可以"LocalSystem"。
如果服务类型为 SERVICE_KERNEL_DRIVER 或 SERVICE_FILE_SYSTEM_DRIVER,此成员是驱动程序对象名称 (即,\FileSystem\Rdr 或 \Driver\Xns),输入和输出 (I/O) 系统使用加载设备驱动程序。如果此成员为 NULL,驱动程序是由 I/O 系统,根据服务名称创建的默认对象名称运行。

lpDisplayName:服务描述。能超过类型为 REG_SZ 注册表值的大小。也可以指定为这样:@[path\]dllname,-strID。请参见MSDN文档的RegLoadMUIString

cbBufSize:以字节为单位的缓冲区的大小

pcbBytesNeeded:如果缓冲区太小,指向接收的需要返回剩余的服务条目的字节数的变量的指针。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

11。QueryServiceConfig2 获取服务配置可选参数

BOOL WINAPI QueryServiceConfig2(  _In_      SC_HANDLE hService,  _In_      DWORD     dwInfoLevel,  _Out_opt_ LPBYTE    lpBuffer,  _In_      DWORD     cbBufSize,  _Out_     LPDWORD   pcbBytesNeeded);

hService:服务句柄。此句柄是 OpenService 或 CreateService 函数返回的,并且它必须具有 SERVICE_QUERY_CONFIG 访问权限。

dwInfoLevel:要查询的配置信息。此参数可以是下列值之一:

SERVICE_CONFIG_DELAYED_AUTO_START_INFO:LpInfo 参数是指向 SERVICE_DELAYED_AUTO_START_INFO 结构的指针。Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_DESCRIPTION:缓冲区参数是指向 SERVICE_DESCRIPTION 结构的指针。SERVICE_CONFIG_FAILURE_ACTIONS:缓冲区参数是指向 SERVICE_FAILURE_ACTIONS 结构的指针。SERVICE_CONFIG_FAILURE_ACTIONS_FLAG:LpInfo 参数是指向 SERVICE_FAILURE_ACTIONS_FLAG 结构的指针。Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_PREFERRED_NODE:LpInfo 参数是指向 SERVICE_PREFERRED_NODE_INFO 结构的指针。Windows Server 2008、 Windows Vista、 Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_PRESHUTDOWN_INFO:LpInfo 参数是指向 SERVICE_PRESHUTDOWN_INFO 结构的指针。Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO:LpInfo 参数是指向 SERVICE_REQUIRED_PRIVILEGES_INFO 结构的指针。Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_SERVICE_SID_INFO:LpInfo 参数是指向 SERVICE_SID_INFO 结构的指针。Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_TRIGGER_INFO:LpInfo 参数是指向 SERVICE_TRIGGER_INFO 结构的指针。Windows Server 2008、 Windows Vista、 Windows Server 2003 和 Windows XP: 不支持此值。SERVICE_CONFIG_LAUNCH_PROTECTED:LpInfo 参数是一个 SERVICE_LAUNCH_PROTECTED_INFO 结构的指针。此值从 Windows 8.1 开始支持。

lpBuffer:指向接收服务配置信息的缓冲区的指针。此数据的格式取决于 dwInfoLevel 参数的值。
此数组的最大大小为 8k 字节。若要确定所需的大小,请将此参数与 cbBufSize 参数设置为 0。该函数将失败GetLastError返回 ERROR_INSUFFICIENT_BUFFER。PcbBytesNeeded 参数接收所需的大小。

SERVICE_DESCRIPTION 结构:

typedef struct _SERVICE_DESCRIPTION {  LPTSTR lpDescription;} SERVICE_DESCRIPTION, *LPSERVICE_DESCRIPTION;

lpDescription:服务描述。能超过类型为 REG_SZ 注册表值的大小。也可以指定为这样:@[path\]dllname,-strID。请参见MSDN文档的RegLoadMUIString

SERVICE_FAILURE_ACTIONS 结构:

typedef struct _SERVICE_FAILURE_ACTIONS {  DWORD     dwResetPeriod;  LPTSTR    lpRebootMsg;  LPTSTR    lpCommand;  DWORD     cActions;  SC_ACTION *lpsaActions;} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;
dwResetPeriod:以秒为单位,表示服务失败计数在没有错误下重置的时间,INFINITE表示永远不会被重置
lpRebootMsg:要重新启动 SC_ACTION_REBOOT 服务控制器动作响应之前广播到服务器的用户的消息。对于修改配置,如果此值为 NULL,重新启动消息是不变的。如果值为空字符串 (""),重新启动消息将被删除并没有消息被广播。
lpCommand:响应 SC_ACTION_RUN_COMMAND 时执行进程的命令行。这一过程在相同的服务帐户下运行。对于修改配置,如果此值为 NULL,该命令是不变的。如果值为空字符串 (""),该命令删除并且服务失败时不运行任何程序。
cActions:LpsaActions 数组中的元素数。对于修改配置,如果此值为 0,但 lpsaActions 不是 NULL,删除重置期间和失败操作的数组。
lpsaActions:指向一个 SC_ACTION 结构数组的指针。对于修改配置,如果此值为 NULL,则忽略,cActions 和 dwResetPeriod 的成员。
SC_ACTION 结构:
typedef struct _SC_ACTION {  SC_ACTION_TYPE Type;  DWORD          Delay;} SC_ACTION, *LPSC_ACTION;
Type:要执行的操作。此成员可以是下列之一:
SC_ACTION_NONE:没有行动。SC_ACTION_REBOOT:重新启动计算机。SC_ACTION_RESTART:重新启动该服务。SC_ACTION_RUN_COMMAND:运行一个命令。
Delay:在执行指定的操作,以毫秒为单位之前等待的时间。
备注:服务启动失败时,系统启动的次数进行计数。经过 dwResetPeriod 秒时,计数重置为 0。当服务失败第 n 次时,服务控制器执行 lpsaActions 数组中的元素 [N-1] 中指定的操作。如果 N 大于 cActions,服务控制器重复上次操作数组中。

cbBufSize:以字节为单位的缓冲区的大小

pcbBytesNeeded:如果缓冲区太小,指向接收的需要返回剩余的服务条目的字节数的变量的指针。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

12。ChangeServiceConfig 修改服务配置参数

BOOL WINAPI ChangeServiceConfig(  _In_      SC_HANDLE hService,  _In_      DWORD     dwServiceType,  _In_      DWORD     dwStartType,  _In_      DWORD     dwErrorControl,  _In_opt_  LPCTSTR   lpBinaryPathName,  _In_opt_  LPCTSTR   lpLoadOrderGroup,  _Out_opt_ LPDWORD   lpdwTagId,  _In_opt_  LPCTSTR   lpDependencies,  _In_opt_  LPCTSTR   lpServiceStartName,  _In_opt_  LPCTSTR   lpPassword,  _In_opt_  LPCTSTR   lpDisplayName);

hService:服务句柄。此句柄是OpenService 或 CreateService函数返回的,并且必须具有 SERVICE_CHANGE_CONFIG 访问权限。

从 dwServiceType 到 lpServiceStartName :参见上面的QUERY_SERVICE_CONFIG结构(快速跳转)

lpPassword:LpServiceStartName 参数所指定的帐户名称的密码。如果您不更改现有的密码,请指定 NULL。如果该帐户没有密码,或在本地、 网络服务或本地系统帐户运行该服务,请指定空字符串。

lpDisplayName:服务描述。能超过类型为 REG_SZ 注册表值的大小。也可以指定为这样:@[path\]dllname,-strID。请参见MSDN文档的RegLoadMUIString

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

13。ChangeServiceConfig2 修改服务配置可选参数

BOOL WINAPI ChangeServiceConfig2(  _In_     SC_HANDLE hService,  _In_     DWORD     dwInfoLevel,  _In_opt_ LPVOID    lpInfo);

hService:服务的句柄。此句柄是OpenService 或 CreateService函数返回的,并且必须具有 SERVICE_CHANGE_CONFIG 访问权限。

dwInfoLevel:见上面QueryServiceConfig2的相关内容(快速跳转)

lpInfo:见上面QueryServiceConfig2的相关内容(快速跳转)

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

示例源码:
参数说明和代码注释就不写了,如果看过上文理解下面的很轻松。
①枚举服务
BOOL WINAPI ListWin32Service(){SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);if (hSCManager != NULL){DWORD BytesNeeded;DWORD count;EnumServicesStatus(hSCManager, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &BytesNeeded, &count, 0);char* buffer = new char[BytesNeeded];RtlZeroMemory(buffer, BytesNeeded);ENUM_SERVICE_STATUS* Services = (ENUM_SERVICE_STATUS*)buffer;if (EnumServicesStatus(hSCManager, SERVICE_WIN32, SERVICE_STATE_ALL, Services, BytesNeeded, &BytesNeeded, &count, 0)){for (int i = 0; i < count; i++) _putts(Services[i].lpServiceName);delete[] buffer;return TRUE;}delete[] buffer;CloseServiceHandle(hSCManager);return FALSE;}else return FALSE;}

②修改服务描述
BOOL WINAPI SetServiceDescription(LPCTSTR ServiceName, LPTSTR Description){SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);if (hSCManager != NULL){SC_HANDLE hService = OpenService(hSCManager, ServiceName, SERVICE_CHANGE_CONFIG);if (hService != NULL){SERVICE_DESCRIPTION desc;desc.lpDescription = Description;if (ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)){CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return TRUE;}CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return FALSE;}CloseServiceHandle(hSCManager);return FALSE;}else return FALSE;}

③让服务启动失败后总是恢复
BOOL WINAPI LetServiceAlwaysReboot(LPCTSTR ServiceName){SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);if (hSCManager != NULL){SC_HANDLE hService = OpenService(hSCManager, ServiceName, SC_MANAGER_ALL_ACCESS);//值得一提的是需要用SC_MANAGER_ALL_ACCESSif (hService != NULL){SERVICE_FAILURE_ACTIONS failact = { 0 };SC_ACTION act[3];act[0].Delay = act[1].Delay = act[2].Delay = 0;act[0].Type = act[1].Type = act[2].Type = SC_ACTION_RESTART;failact.cActions = 3;failact.lpsaActions = act;failact.dwResetPeriod = 0;if (ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &failact)){CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return TRUE;}CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return FALSE;}CloseServiceHandle(hSCManager);return FALSE;}else return FALSE;}



0 0
原创粉丝点击