什么是Windows服務(wù)
在運(yùn)行框中輸入如下命令點(diǎn)擊確定:

在這列表里面的程序均為Windows服務(wù)。服務(wù)能夠在沒(méi)有用戶登錄的情況下運(yùn)行。

大部分情況下,我們將某個(gè)程序編寫(xiě)為服務(wù)的主要目的是程序需要長(zhǎng)時(shí)間運(yùn)行且不需要界面或當(dāng)程序異常退出和系統(tǒng)重啟時(shí),希望程序能夠自啟動(dòng)。某些進(jìn)程提權(quán)操作也可能需要服務(wù)來(lái)實(shí)現(xiàn)。
Windows服務(wù)的類型
- 服務(wù)程序
服務(wù)程序就是普通的服務(wù)程序,我們大部分寫(xiě)的都是這個(gè)。
- 服務(wù)配置程序
主要用來(lái)查詢和調(diào)整服務(wù)的程序,即服務(wù)程序的安裝和刪除操作等。
- 服務(wù)控制程序
主要用來(lái)啟動(dòng)和控制服務(wù)的程序,即處理服務(wù)中的一些請(qǐng)求。
以上內(nèi)容詳細(xì)區(qū)別請(qǐng)查看官方文檔= =。
服務(wù)控制管理器(Service control manager, SCM)
簡(jiǎn)單來(lái)說(shuō)SCM是用來(lái)管理整個(gè)服務(wù)的程序,SCM會(huì)隨系統(tǒng)啟動(dòng)而啟動(dòng)。SCM本質(zhì)是一個(gè)遠(yuǎn)程調(diào)用服務(wù),也就是說(shuō)可以SCM可以在遠(yuǎn)程機(jī)器上操作。
SCM主要的功能如下:
- 維護(hù)已安裝的服務(wù)
- 隨系統(tǒng)啟動(dòng)而開(kāi)啟服務(wù),或者通過(guò)命令開(kāi)啟
- 枚舉所有已安裝的服務(wù)
- 維護(hù)正在運(yùn)行服務(wù)的狀態(tài)
- 發(fā)送控制請(qǐng)求到正在運(yùn)行的服務(wù)
- 鎖定和解鎖服務(wù)數(shù)據(jù)庫(kù)
SCM維護(hù)了一個(gè)所有已安裝服務(wù)的數(shù)據(jù)庫(kù),這個(gè)數(shù)據(jù)庫(kù)位置在注冊(cè)表中,位于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
除了通過(guò)上面界面查看服務(wù),也可以通過(guò)OpenSCManager打開(kāi)一個(gè)SCM管理器,然后使用EnumServicesStatusEx枚舉所有的服務(wù),代碼如下。(注意程序需要在管理員權(quán)限下運(yùn)行)
#include <Windows.h>
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "chs");
// 打開(kāi)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;
// 枚舉服務(wù)
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;
}
}
// 注意要關(guān)閉SCM
CloseServiceHandle(scHandle);
return 0;
}
參考文獻(xiàn)
https://docs.microsoft.com/en-us/windows/win32/services/about-services