枚举Windows系统服务,通过进程ID取服务名



//枚举Windows系统服务

//使用到的函数以及MSDN的说明如下:
//1、OpenSCManager说明
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms684323(v=vs.85).aspx

//2、EnumServicesStatusEx说明
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms682640(v=vs.85).aspx

//3、CloseServiceHandle说明
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms682028(v=vs.85).aspx

// 测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
int main(int argc, char *argv[])
{
	LONG lRet = 0;
	BOOL bRet = FALSE;
	SC_HANDLE hSCM = NULL;              // 服务数据库句柄
	char *pBuf = NULL;                  // 缓冲区指针
	DWORD dwBufSize = 0;                // 传入的缓冲长度
	DWORD dwBufNeed = 0;                // 需要的缓冲长度
	DWORD dwNumberOfService = 0;        // 返回的服务个数
	ENUM_SERVICE_STATUS_PROCESS *pServiceInfo = NULL;   // 服务信息

	// 建立了一个到服务控制管理器的连接,并打开指定的数据库
	hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
	if(NULL == hSCM)
	{
		printf("OpenSCManager error.\n");
		return -1;
	}

	// 获取需要的缓冲区大小
	EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, 
		NULL, dwBufSize, &dwBufNeed, &dwNumberOfService, NULL, NULL);

	// 多设置存放1个服务信息的长度
	dwBufSize = dwBufNeed + sizeof(ENUM_SERVICE_STATUS_PROCESS);
	pBuf = (char *)malloc(dwBufSize);
	if(NULL == pBuf)
	{
		printf("malloc error.\n");
		return -1;
	}
	memset(pBuf, 0, dwBufSize);

	// 获取服务信息
	bRet = EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, 
		(LPBYTE)pBuf, dwBufSize, &dwBufNeed, &dwNumberOfService, NULL, NULL);
	if(bRet == FALSE)
	{
		printf("EnumServicesStatusEx error.\n");
		::CloseServiceHandle(hSCM);
		free(pBuf);
		return -1;
	}
	// 关闭打开的服务句柄
	bRet = ::CloseServiceHandle(hSCM);
	if(bRet == FALSE)
	{
		printf("CloseServiceHandle error.\n");
	}
	printf("Service Num:%d\n", dwNumberOfService);

	pServiceInfo = (LPENUM_SERVICE_STATUS_PROCESS)pBuf;
	// 打印取得的服务信息
	for(unsigned int i = 0; i < dwNumberOfService; i++)
	{
		printf("----------%d----------\n", i);
		printf("DisplayName \t\t : %s \n", pServiceInfo[i].lpDisplayName);
		printf("ServiceName \t\t : %s \n", pServiceInfo[i].lpServiceName);
		printf("ServiceType \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwServiceType);
		printf("CurrentState \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwCurrentState);
		printf("ControlsAccepted \t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwControlsAccepted);
		printf("Win32ExitCode \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwWin32ExitCode);
		printf("ServiceSpecificExitCode  : %d \n", pServiceInfo[i].ServiceStatusProcess.dwServiceSpecificExitCode);
		printf("CheckPoint \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwCheckPoint);
		printf("WaitHint \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwWaitHint);
		printf("Process Id \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwProcessId);
		printf("ServiceFlags \t\t : %d \n", pServiceInfo[i].ServiceStatusProcess.dwServiceFlags);
	}
	free(pBuf);
	system("PAUSE");
	return 0;
}


// 既然能够获取到所有的服务信息,
// 那么根据进程ID查询该进程是否为服务,取得服务名等一系列的操作就可以按自己的需求来完成了
// 获取进程ID GetCurrentProcessId()



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows 服务中,您可以使用以下代码片段来获管理员权限的进程安装路径: ```c++ #include <Windows.h> #include <iostream> #include <string> // 获指定进程的完整路径 std::wstring GetProcessPath(DWORD pid) { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); if (!hProcess) { return L""; } wchar_t path[MAX_PATH] = { 0 }; DWORD size = GetModuleFileNameEx(hProcess, NULL, path, MAX_PATH); CloseHandle(hProcess); if (size == 0) { return L""; } return std::wstring(path); } // 从注册表中获指定进程的安装路径 std::wstring GetProcessInstallPath(const std::wstring& processName) { HKEY hKey; LONG result = ERROR_SUCCESS; // 打开注册表项 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths", 0, KEY_READ | KEY_WOW64_32KEY, &hKey); if (result != ERROR_SUCCESS) { return L""; } // 枚举所有子键 wchar_t valueName[MAX_PATH] = { 0 }; DWORD index = 0, size = MAX_PATH; while (RegEnumKeyExW(hKey, index++, valueName, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { size = MAX_PATH; // 判断子键称是否为指定进程 if (_wcsicmp(valueName, processName.c_str()) == 0) { // 获子键的默认键值(即用程序的完整路径) wchar_t path[MAX_PATH] = { 0 }; DWORD dataSize = MAX_PATH * sizeof(wchar_t); result = RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)path, &dataSize); RegCloseKey(hKey); if (result == ERROR_SUCCESS) { return std::wstring(path); } else { return L""; } } } RegCloseKey(hKey); return L""; } int main() { // 获当前进程ID DWORD pid = GetCurrentProcessId(); // 获当前进程的完整路径 std::wstring processPath = GetProcessPath(pid); // 获当前进程的文件 std::wstring processName = processPath.substr(processPath.rfind(L"\\") + 1); // 获当前进程的安装路径 std::wstring installPath = GetProcessInstallPath(processName); std::wcout << L"Install path: " << installPath << std::endl; return 0; } ``` 在上面的代码中,我们首先使用 `GetProcessPath()` 函数获指定进程的完整路径,然后从中提进程。接着,我们使用 `GetProcessInstallPath()` 函数从注册表中查找指定进程的安装路径。在该函数中,我们首先打开 `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths` 注册表项,并枚举其中的所有子键。对于每个子键,我们判断称是否为指定进程,如果是,则从其默认键值中获用程序的完整路径,并返回该路径。最后,我们在 `main()` 函数中调用上述两个函数,并输出获到的安装路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值