//ServiceInfoCollect.h
#pragma once#include //服务状态信息
typedef struct tagServiceInfo
{char szDisplayName[MAX_PATH]; //显示名称char szServiceName[MAX_PATH]; //服务名char szLoginUser[MAX_PATH]; //启动账户名DWORD dwCurrentState; //服务状态DWORD dwServiceType;char szBinaryPathName[MAX_PATH]; //进程路径char szDescription[1024]; //描述DWORD dwProcessId;
}ServiceInfo;class ServiceInfoCollect
{
public:ServiceInfoCollect();virtual ~ServiceInfoCollect();//枚举所有的服务BOOL GetAllService(std::list & lstServiceInfo);//启动一个服务BOOL StartOneService(char *pServiceName);//停止一个服务BOOL StopOneService(char *pServiceName);
};
//ServiceInfoCollect.cpp
#include "stdafx.h"
#include "ServiceInfoCollect.h"
#include #define MAX_SERVICE_COUNT 1024 //最大服务数//获取进程名称
BOOL GetProcessNameByProcessId(DWORD lProcessID, char *pProcessPathName)
{BOOL bRet &#61; FALSE;DWORD dwMajorVersion &#61; 0;DWORD dwMinorVersion &#61; 0;OSVERSIONINFOEX osver &#61; { 0 };osver.dwOSVersionInfoSize &#61; sizeof(osver);::GetVersionEx((OSVERSIONINFO*)&osver);dwMajorVersion &#61; osver.dwMajorVersion;dwMinorVersion &#61; osver.dwMinorVersion;//打开进程HANDLE hProcess &#61; OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,//访问权限false,//是否允许得到的进程句柄被后创建的子进程继承lProcessID);//进程IDif (hProcess){bRet &#61; TRUE;//获取进程名char szPathName[MAX_PATH] &#61; { 0 }; //进程名if (dwMajorVersion <5) //&#61; 6) //win7或win7以上{DWORD dwPathNameSize &#61; sizeof(szPathName);BOOL bSuccessProcess &#61; TRUE;bSuccessProcess &#61; QueryFullProcessImageName(hProcess, 0, szPathName, &dwPathNameSize);strcpy(pProcessPathName, szPathName);if (!bSuccessProcess){bRet &#61; FALSE;}}::CloseHandle(hProcess);}return bRet;
}ServiceInfoCollect::ServiceInfoCollect()
{
}ServiceInfoCollect::~ServiceInfoCollect()
{
}//枚举所有的服务
BOOL ServiceInfoCollect::GetAllService(std::list & lstServiceInfo)
{lstServiceInfo.clear();char *pBuf &#61; NULL; // 缓冲区指针DWORD dwBufSize &#61; 0; // 传入的缓冲长度DWORD dwBufNeed &#61; 0; // 需要的缓冲长度DWORD dwNumberOfService &#61; 0; // 返回的服务个数ENUM_SERVICE_STATUS_PROCESS *pServiceInfo &#61; NULL; // 服务信息BOOL bRet &#61; FALSE;ServiceInfo info &#61; { 0 };SC_HANDLE hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM &#61;&#61; NULL){hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);}if (hSCM &#61;&#61; NULL){return FALSE;}// 获取需要的缓冲区大小EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,NULL, dwBufSize, &dwBufNeed, &dwNumberOfService, NULL, NULL);// 多设置存放1个服务信息的长度dwBufSize &#61; dwBufNeed &#43; sizeof(ENUM_SERVICE_STATUS_PROCESS);pBuf &#61; (char *)malloc(dwBufSize);if (NULL &#61;&#61; pBuf){//printf("malloc error.\n");return FALSE;}memset(pBuf, 0, dwBufSize);// 获取服务信息bRet &#61; EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,(LPBYTE)pBuf, dwBufSize, &dwBufNeed, &dwNumberOfService, NULL, NULL);if (bRet &#61;&#61; FALSE){//printf("EnumServicesStatusEx error.\n");::CloseServiceHandle(hSCM);free(pBuf);return FALSE;}pServiceInfo &#61; (LPENUM_SERVICE_STATUS_PROCESS)pBuf;SC_HANDLE sh;char* szInfo[MAX_SERVICE_COUNT * 8] &#61; { 0 };DWORD dwSize &#61; MAX_SERVICE_COUNT * 8;for (unsigned int i &#61; 0; i lpDescription !&#61; NULL){if (strlen(((LPSERVICE_DESCRIPTION)szInfo)->lpDescription) >&#61; 1024){memcpy(info.szDescription, ((LPSERVICE_DESCRIPTION)szInfo)->lpDescription, 1023);}else{sprintf_s(info.szDescription, 1024 - 1, ((LPSERVICE_DESCRIPTION)szInfo)->lpDescription);}}//得到服务的启动账户名bRet &#61; QueryServiceConfig(sh, (LPQUERY_SERVICE_CONFIG)szInfo, dwSize, &dwSize);if (bRet){sprintf_s(info.szLoginUser, MAX_PATH - 1, ((LPQUERY_SERVICE_CONFIG)szInfo)->lpServiceStartName);sprintf_s(info.szBinaryPathName, MAX_PATH - 1, ((LPQUERY_SERVICE_CONFIG)szInfo)->lpBinaryPathName);}else{GetProcessNameByProcessId(info.dwProcessId, info.szBinaryPathName);}CloseServiceHandle(sh);}lstServiceInfo.push_back(info);}CloseServiceHandle(hSCM);free(pBuf);return TRUE;
}//启动一个服务
BOOL ServiceInfoCollect::StartOneService(char *pServiceName)
{SC_HANDLE hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM &#61;&#61; NULL){hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);}if (hSCM &#61;&#61; NULL){return FALSE;}SC_HANDLE sh &#61; OpenService(hSCM, pServiceName, SERVICE_ALL_ACCESS);if (sh &#61;&#61; NULL){sh &#61; OpenService(hSCM, pServiceName, SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS);}if (sh &#61;&#61; NULL){CloseServiceHandle(hSCM);return FALSE;}//启动服务SERVICE_STATUS status;BOOL bSuccess &#61; QueryServiceStatus(sh, &status);if (!bSuccess){CloseServiceHandle(sh);CloseServiceHandle(hSCM);return FALSE;}if (status.dwCurrentState !&#61; SERVICE_RUNNING){bSuccess &#61; StartService(sh, 0, NULL);if (!bSuccess){CloseServiceHandle(sh);CloseServiceHandle(hSCM);return FALSE;}}CloseServiceHandle(sh);CloseServiceHandle(hSCM);return TRUE;
}//停止一个服务
BOOL ServiceInfoCollect::StopOneService(char *pServiceName)
{SC_HANDLE hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM &#61;&#61; NULL){hSCM &#61; OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);}if (hSCM &#61;&#61; NULL){return FALSE;}SC_HANDLE sh &#61; OpenService(hSCM, pServiceName, SERVICE_ALL_ACCESS);if (sh &#61;&#61; NULL){sh &#61; OpenService(hSCM, pServiceName, SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS);}if (sh &#61;&#61; NULL){CloseServiceHandle(hSCM);return FALSE;}//启动服务SERVICE_STATUS status;BOOL bSuccess &#61; QueryServiceStatus(sh, &status);if (!bSuccess){CloseServiceHandle(sh);CloseServiceHandle(hSCM);return FALSE;}if (status.dwCurrentState !&#61; SERVICE_STOPPED){bSuccess &#61; ControlService(sh, SERVICE_STOPPED, &status);if (!bSuccess){CloseServiceHandle(sh);CloseServiceHandle(hSCM);return FALSE;}}CloseServiceHandle(sh);CloseServiceHandle(hSCM);return TRUE;
}
服务启动、停止等需要管理员权限&#xff0c;否则容易失败。
参考资料&#xff1a;
https://blog.csdn.net/lanuage/article/details/51902075
https://blog.csdn.net/dgyanyong/article/details/40209069