Windows服务编程

来源:互联网 发布:手机淘宝如何充话费 编辑:程序博客网 时间:2024/05/08 03:37

先说明,本文不是编写服务,而是编程控制已有的服务。

服务是一种程序类型,它在后台运行,服务程序通常可以在本地和通过网络为用户提供一些功能。服务程序可能是EXE程序,具有其单独的进程,也有可能是DLL文件依附于某个进程,更有可能是SYS文件而处于系统的内核之中。

在Windows下,可以在“我的电脑”上单击鼠标右键,然后再弹出的菜单上选择“管理”,打开“计算机管理工具”,单击左面树形列表的“服务和应用程序”会打开子列表,选择“服务”,则在右侧出现服务列表项。也可以直接在“运行”窗口输入“services.msc”,打开服务管理器。服务管理器主要用于显示系统中已经存在的应用程序服务,显示对服务的描述,还可以控制服务的启动状态和启动方式。服务管理器界面如下图示:


服务编程常用API如下:

1. 打开服务管理器

SC_HANDLEOpenSCManager( LPCTSTR lpMachineName,//指向欲打开服务控制器数据库的目标主机名,本机则设置为NULLLPCTSTRlpDatabaseName,//指向目标主机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)




0 0