什么是Windows服务
在运行框中输入如下命令点击确定:
在这列表里面的程序均为Windows服务。服务能够在没有用户登录的情况下运行。
大部分情况下,我们将某个程序编写为服务的主要目的是程序需要长时间运行且不需要界面或当程序异常退出和系统重启时,希望程序能够自启动。某些进程提权操作也可能需要服务来实现。
Windows服务的类型
- 服务程序
服务程序就是普通的服务程序,我们大部分写的都是这个。
- 服务配置程序
主要用来查询和调整服务的程序,即服务程序的安装和删除操作等。
- 服务控制程序
主要用来启动和控制服务的程序,即处理服务中的一些请求。
以上内容详细区别请查看官方文档= =。
服务控制管理器(Service control manager, SCM)
简单来说SCM是用来管理整个服务的程序,SCM会随系统启动而启动。SCM本质是一个远程调用服务,也就是说可以SCM可以在远程机器上操作。
SCM主要的功能如下:
- 维护已安装的服务
- 随系统启动而开启服务,或者通过命令开启
- 枚举所有已安装的服务
- 维护正在运行服务的状态
- 发送控制请求到正在运行的服务
- 锁定和解锁服务数据库
SCM维护了一个所有已安装服务的数据库,这个数据库位置在注册表中,位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
除了通过上面界面查看服务,也可以通过OpenSCManager
打开一个SCM管理器,然后使用EnumServicesStatusEx
枚举所有的服务,代码如下。(注意程序需要在管理员权限下运行)
#include <Windows.h>
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "chs");
// 打开SCM管理器
SC_HANDLE scHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (scHandle == NULL)
{
printf("open scm manager failed!\n");
return 0;
}
DWORD bufSize = 0;
DWORD bytesNeeded = 0;
DWORD servicesReturned = 0;
DWORD resumeHandle = 0;
BYTE* services = NULL;
// 枚举服务
while (true)
{
BOOL ret = EnumServicesStatusEx(
scHandle,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL, services, bufSize,
&bytesNeeded, &servicesReturned, &resumeHandle, NULL);
if (ret == 0 && GetLastError() == ERROR_MORE_DATA)
{
if (bytesNeeded > bufSize)
{
if (services != NULL)
{
free(services);
services = NULL;
}
bufSize = bytesNeeded;
services = (BYTE*)malloc(bufSize);
if (services)
{
memset(services, 0, bufSize);
}
}
}
else if (ret == 0)
{
printf("enum failed!\n");
break;
}
else if (ret != 0)
{
printf("The number of services: %u\n", servicesReturned);
ENUM_SERVICE_STATUS_PROCESS* pServiceInfo = (LPENUM_SERVICE_STATUS_PROCESS)services;
if (pServiceInfo)
{
for (DWORD i = 0; i < servicesReturned; i++)
{
printf("DisplayName: %ls\n", pServiceInfo[i].lpDisplayName);
}
}
break;
}
}
// 注意要关闭SCM
CloseServiceHandle(scHandle);
return 0;
}
参考文献
https://docs.microsoft.com/en-us/windows/win32/services/about-services