先说明,本文不是编写服务,而是编程控制已有的服务。
服务是一种程序类型,它在后台运行,服务程序通常可以在本地和通过网络为用户提供一些功能。服务程序可能是EXE程序,具有其单独的进程,也有可能是DLL文件依附于某个进程,更有可能是SYS文件而处于系统的内核之中。
在Windows下,可以在“我的电脑”上单击鼠标右键,然后再弹出的菜单上选择“管理”,打开“计算机管理工具”,单击左面树形列表的“服务和应用程序”会打开子列表,选择“服务”,则在右侧出现服务列表项。也可以直接在“运行”窗口输入“services.msc”,打开服务管理器。服务管理器主要用于显示系统中已经存在的应用程序服务,显示对服务的描述,还可以控制服务的启动状态和启动方式。服务管理器界面如下图示:
服务编程常用API如下:
1. 打开服务管理器
SC_HANDLEOpenSCManager( LPCTSTR lpMachineName,//指向欲打开服务控制器数据库的目标主机名,本机则设置为NULL LPCTSTRlpDatabaseName,//指向目标主机SCM数据库名字字符串 DWORD dwDesiredAccess//指定对SCM数据库的访问权限 );
2. 关闭服务句柄
BOOL CloseServiceHandle( SC_HANDLEhSCObject//要关闭的服务或服务管理器句柄 );
3.服务的枚举
BOOL EnumServicesStatus( SC_HANDLE hSCManager,//OpenSCManager函数返回的句柄 DWORD dwServiceType,//指定枚举服务类型 DWORD dwServiceState,//枚举指定状态的服务 LPENUM_SERVICE_STATUS lpServices,//结构体指针 DWORD cbBufSize,//指定缓冲区大小 LPDWORD pcbBytesNeeded,//返回实际使用的内存空间大小 LPDWORD lpServicesReturned,//返回枚举服务的个数 LPDWORD lpResumeHandle//返回枚举是否成功 );
4.打开指定服务
SC_HANDLEOpenService( SC_HANDLE hSCManager,//指定由OpenSCManager函数打开的服务句柄 LPCTSTR lpServiceName,//指定要打开的服务名称 DWORD dwDesiredAccess//打开服务的访问权限,为了方便,可指定为SC_MANAGER_ALL_ACCESS。 );
5.启动服务
BOOL StartService( SC_HANDLE hService,//指定要启动服务的句柄,该句柄由OpenService函数返回 DWORD dwNumServiceArgs,//指向启动服务所需的参数个数 LPCTSTR* lpServiceArgVectors//指向启动服务的参数 );
6.停止服务
BOOL ControlService( SC_HANDLE hService,//指定一个由OpenService打开的服务句柄 DWORD dwControl,//指定要发送的控制码 LPSERVICE_STATUS lpServiceStatus//返回服务的状态 );
ControlService()可以对服务进行多种控制,每种控制操作对应一种控制码。当要停止服务时,使用的控制码是SERVICE_CONTROL_STOP。
下面我们就写一个工程,实现电脑上Win32程序服务与驱动服务的分别展示,并且可以停止或者启动其中指定的服务。
用MFC搭建一个有如下界面的Dialog程序:
每个控件的作用相信大家都看得出来,界面方面的知识就不一一介绍了,直接上关键的控制代码。
其中CListCtrl控件的初始化可以参考注册表操作那篇博客。
实现服务枚举的代码如下:
VOID CMyDlg::ShowServiceList(DWORD dwServiceType)//参数是要枚举的服务类型 { m_ServiceList.DeleteAllItems(); //打开服务管理器 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == hSCM) { AfxMessageBox("Open SCManager Error!"); return; } DWORD ServiceCount = 0; DWORD dwSize = 0; LPENUM_SERVICE_STATUS lpInfo; //第一次调用 BOOL bRet = EnumServicesStatus(hSCM, dwServiceType, SERVICE_STATE_ALL, NULL,0,&dwSize, &ServiceCount,NULL); /* 由于没有给定接收服务列表的缓冲区,这里必定会调用失败 失败的返回值时ERROR_MORE_DATA 说明需要更大的缓冲区来保存数据 */ if(!bRet && GetLastError() == ERROR_MORE_DATA) { //分配缓冲区保存服务列表 lpInfo = (LPENUM_SERVICE_STATUS)(new BYTE[dwSize]); bRet = EnumServicesStatus(hSCM, dwServiceType, SERVICE_STATE_ALL, (LPENUM_SERVICE_STATUS)lpInfo, dwSize,&dwSize, &ServiceCount,NULL); if(!bRet) { CloseServiceHandle(hSCM); return; } //逐个获取数据,添加至列表控件 for(DWORD i = 0; i < ServiceCount; ++i) { CString str; m_ServiceList.InsertItem(i, lpInfo[i].lpServiceName); m_ServiceList.SetItemText(i, 1, lpInfo[i].lpDisplayName); switch(lpInfo[i].ServiceStatus.dwCurrentState) { case SERVICE_PAUSED: { m_ServiceList.SetItemText(i, 2, "暂停"); break; } case SERVICE_STOPPED: { m_ServiceList.SetItemText(i, 2, "停止"); break; } case SERVICE_RUNNING: { m_ServiceList.SetItemText(i, 2, "运行"); break; } default: { m_ServiceList.SetItemText(i, 2, "其它"); } } } //释放申请的空间 delete lpInfo; } //关闭服务管理器句柄 CloseServiceHandle(hSCM); }
启动服务的代码:
void CMyDlg::OnBtnStart() { //选择服务的索引 POSITION Pos = m_ServiceList.GetFirstSelectedItemPosition(); int nSelect = -1; while(Pos) { nSelect = m_ServiceList.GetNextSelectedItem(Pos); } if(-1 == nSelect) { AfxMessageBox("请选择要启动的服务"); return; } //获取选择的服务的服务名 char szServiceName[MAXBYTE] = {0}; m_ServiceList.GetItemText(nSelect, 0, szServiceName, MAXBYTE); SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == hSCM) { AfxMessageBox("Open SCManager Eorror"); return; } //打开指定的服务 SC_HANDLE hCService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS); //启动服务 BOOL bRet = StartService(hCService, 0, NULL); if(bRet == TRUE) { m_ServiceList.SetItemText(nSelect, 2, "运行"); }else{ AfxMessageBox("启动失败"); } CloseServiceHandle(hCService); CloseServiceHandle(hSCM); }
停止服务的代码:
void CMyDlg::OnBtnStop() { //选择服务的索引 POSITION Pos = m_ServiceList.GetFirstSelectedItemPosition(); int nSelect = -1; while(Pos) { nSelect = m_ServiceList.GetNextSelectedItem(Pos); } if(-1 == nSelect) { AfxMessageBox("请选择要停止的服务"); return; } //获取选择的服务的服务名 char szServiceName[MAXBYTE] = {0}; m_ServiceList.GetItemText(nSelect, 0, szServiceName, MAXBYTE); // SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == hSCM) { AfxMessageBox("Open SCManager Eoor"); return; } //打开指定的服务 SC_HANDLE hSCService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS); SERVICE_STATUS ServiceStatus; //停止服务 BOOL bRet = ControlService(hSCService, SERVICE_CONTROL_STOP, &ServiceStatus); if(bRet == TRUE) { m_ServiceList.SetItemText(nSelect, 2, "停止"); }else{ AfxMessageBox("服务停止失败"); } CloseServiceHandle(hSCService); CloseServiceHandle(hSCM); }
最后再亲情奉上本项目源码供大家参考,当然,我得收5积分的敲代码辛苦费。可以在我上传的资源上查:服务编程(blog)
时间: 2024-11-12 16:00:44