windows api
OpenSCManager
function OpenSCManager(
lpMachineName: PChar,
lpDatabaseName: PChar,
dwDesiredAccess: DWORD): SC_HANDLE; stdcall;
参数
lpMachineName
指向零终止字符串,指定目标计算机的名称。如果该指针为NULL ,或者它指向一个空字符串,那么该函数连接到本地计算机上的服务控制管理器。
lpDatabaseName
指向零终止字符串,指定将要打开的服务控制管理数据库的名称。此字符串应被置
为 SERVICES_ACTIVE_DATABASE。如果该指针为NULL ,则打开默认的 SERVICES_ACTIVE_DATABASE
数据库。
dwDesiredAccess
指定服务访问控制管理器的权限。在授予要求的权限前,系统会检查调用进程的权限令牌,该令牌针对与服
务控制管理器相关的安全描述符的权限控制列表。此外,该函数的调用将隐式地指定
SC_MANAGER_CONNECT 的访问权限。
此外,下列服务控制管理器对象的访问类型可以被指定:
SC_MANAGER_ALL_ACCESS 除了所有此表中列出的访问类型,还包括
STANDARD_RIGHTS_REQUIRED。
SC_MANAGER_CONNECT 可以连接到服务控制管理器。
SC_MANAGER_CREATE_SERVICE 使要求的CreateService函数创建一个服务对象,并将其添加到数
据库中。
SC_MANAGER_ENUMERATE_SERVICE 使要求的EnumServicesStatus功能清单的服务,这是在数据库
中。
SC_MANAGER_LOCK 使要求的LockServiceDatabase功能获得锁定数据库。
SC_MANAGER_QUERY_LOCK_STATUS 使要求的QueryServiceLockStatus检索功能锁定状态信息的数据
库。
OpenService
SC_HANDLE WINAPI OpenService(
In SC_HANDLE hSCManager,
In LPCTSTR lpServiceName,
In DWORD dwDesiredAccess
);
Parameters
hSCManager [in]
A handle to the service control manager database. The OpenSCManager function returns this handle. For more information, see Service Security and Access Rights.
lpServiceName [in]
The name of the service to be opened. This is the name specified by the lpServiceName parameter of the CreateService function when the service object was created, not the service display name that is shown by user interface applications to identify the service.
The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and backslash () are invalid service name characters.
dwDesiredAccess [in]
The access to the service. For a list of access rights, see Service Security and Access Rights.
Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service object.
Return value
If the function succeeds, the return value is a handle to the service.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.
QueryServiceStatusEx
BOOL WINAPI QueryServiceStatusEx(
In SC_HANDLE hService,
In SC_STATUS_TYPE InfoLevel,
Out_opt LPBYTE lpBuffer,
In DWORD cbBufSize,
Out LPDWORD pcbBytesNeeded
);
Parameters
hService
[in] Handle to the service. This handle is returned by the CreateService or OpenService function, and it must have the SERIVCE_QUERY_STATUS access right. For more information, see Service Security and Access Rights.
InfoLevel
[in] Service attributes to be returned. Use SC_STATUS_PROCESS_INFO to retrieve the service status information. The lpBuffer parameter is a pointer to a SERVICE_STATUS_PROCESS structure.
Currently, no other information levels are defined.
lpBuffer
[out] Pointer to the buffer that receives the status information. The format of this data depends on the value of the InfoLevel parameter.
The maximum size of this array is 8K bytes. To determine the required size, specify NULL for this parameter and 0 for the cbBufSize parameter. The function will fail and GetLastError will return ERROR_INSUFFICIENT_BUFFER. The pcbBytesNeeded parameter will receive the required size.
cbBufSize
[in] Size of the buffer pointed to by the lpBuffer parameter, in bytes.
pcbBytesNeeded
[out] Pointer to a variable that receives the number of bytes needed to store all status information, if the function fails with ERROR_INSUFFICIENT_BUFFER.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError. The following errors can be returned.
上面这三个API是我们用到的,msdn上都有描述,我们应该玩点实在的。
首先明确不要把官方的start service例子所迷惑。
注意一
SC_HANDLE serviceDbHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS)
返回空,错误为0。错误的原因就是,你当前不是管理员账户,所以不能使用SC_MANAGER_ALL_ACCESS,我们应该这样修改:
SC_HANDLE serviceDbHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE|GENERIC_READ );
注意二
schService = OpenService(schSCManager, szSvcName, SERVICE_ALL_ACCESS);
也是返回的0,原因跟上面一样,于是这样修改:
SC_HANDLE serviceHandle = OpenService(serviceDbHandle, szSvcName, SERVICE_QUERY_STATUS);
注意三
如果不是管理员账户,不要试图使用程序开启和停止某一个服务。
查询
SERVICE_STATUS_PROCESS status;
DWORD bytesNeeded;
if(QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO,(LPBYTE) &status,sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded) == NULL)
{
//QueryServiceStatusEx failed
}
if (status.dwCurrentState == SERVICE_RUNNING)
{
}
else if(status.dwCurrentState == SERVICE_STOPPED)
{
}