MFC系统服务开启停止代码

2024-06-14 23:18

本文主要是介绍MFC系统服务开启停止代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

// m_service.cpp : 实现文件
//


#include "stdafx.h"
#include "MFCApplication1.h"
#include "m_service.h"
#include "afxdialogex.h"




// m_service 对话框






m_service *m_this;
HANDLE hThread4;
SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE);
// m_service 对话框
DWORD WINAPI ThreadPro4(LPVOID lpThreadParameter)
{


CRect rt;
m_this->MyList.GetClientRect(rt);
m_this->MyList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
m_this->MyList.InsertColumn(0,_T("服务名"),0,rt.Width( ) / 3);
m_this->MyList.InsertColumn(1,_T("描述"),0,rt.Width( ) / 3);
m_this->MyList.InsertColumn(2,_T("服务状态"),0,rt.Width( ) / 3);


while(true)
{

m_this->MyList.DeleteAllItems( );
DWORD dwServiceNum = 0;
DWORD dwSize = 0;
EnumServicesStatusEx(hSCM,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,//所有服务状态
NULL,0,&dwSize,&dwServiceNum,
NULL,NULL);
//申请需要的内存 第二次调用
LPENUM_SERVICE_STATUS_PROCESS pEnumSerice = (LPENUM_SERVICE_STATUS_PROCESS)LocalAlloc(LPTR,dwSize);
//第二次枚举
BOOL bStattus = EnumServicesStatusEx(hSCM,SC_ENUM_PROCESS_INFO,SERVICE_WIN32,SERVICE_STATE_ALL,(PBYTE)pEnumSerice,dwSize,&dwSize,&dwServiceNum,NULL,NULL);
//遍历信息
for(DWORD i = 0; i < dwServiceNum; i++)
{
m_this->MyList.InsertItem(i,NULL);
m_this->MyList.SetItemText(i,0,pEnumSerice[i].lpServiceName);//服务名
m_this->MyList.SetItemText(i,1,pEnumSerice[i].lpDisplayName);//描述


if(pEnumSerice[i].ServiceStatusProcess.dwCurrentState == 1)
{
m_this->MyList.SetItemText(i,2,L"已停止");//服务类型
}
if(pEnumSerice[i].ServiceStatusProcess.dwCurrentState == 4)
{
m_this->MyList.SetItemText(i,2,L"正在运行");//服务类型
}


}
Sleep(5000);
}




return 0;
}








IMPLEMENT_DYNAMIC(m_service, CDialogEx)


m_service::m_service(CWnd* pParent /*=NULL*/)
: CDialogEx(m_service::IDD, pParent)
{


}


m_service::~m_service()
{
}


void m_service::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX,IDC_LIST1,MyList);
}




BEGIN_MESSAGE_MAP(m_service, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1,&m_service::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2,&m_service::OnBnClickedButton2)
END_MESSAGE_MAP( )




// m_service 消息处理程序




BOOL m_service::OnInitDialog( )
{
CDialogEx::OnInitDialog( );


// TODO:  在此添加额外的初始化






  CRect rc;
  ::GetClientRect(AfxGetApp( )->m_pMainWnd->m_hWnd,rc);
  rc.DeflateRect(0,15,40,90);



m_this = this;
  hThread4 = CreateThread(NULL,NULL,ThreadPro4,(LPVOID)1,NULL,NULL);




return TRUE;  // return TRUE unless you set the focus to a control
// 异常:  OCX 属性页应返回 FALSE
}


BOOL m_service::m_StartService(SC_HANDLE schSCManager,LPTSTR szServiceName)
{


SC_HANDLE schService;
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwOld;
DWORD dwStart;
DWORD dwWaitTime;
DWORD dwByteNeeded;
schService = OpenService(schSCManager,
szServiceName,//服务名字
SERVICE_ALL_ACCESS);//打开服务
if(schService == NULL)
{
return 0;
}
//开始启动服务
if(!StartService(schService,0,NULL))
{
MessageBox(L"启动失败");
return 0;
}
if(!QueryServiceStatusEx(schService,//服务的句柄
SC_STATUS_PROCESS_INFO,//服务状态的信息
(LPBYTE)&ssStatus,//结构体的变量地址
sizeof(SERVICE_STATUS_PROCESS),//结构体的大小
&dwByteNeeded))//储存信息要用的大小
{
//打开失败
return 0;
}
dwStart = GetTickCount( );//毫秒数
dwOld = ssStatus.dwCheckPoint;
while(ssStatus.dwCurrentState == SERVICE_START_PENDING)//判断当前状态
{
dwWaitTime = ssStatus.dwWaitHint / 10;//判断等待时间
if(dwWaitTime < 1000)
{
dwWaitTime = 1000;
}
else if(dwWaitTime > 10000)
{
dwWaitTime = 10000;
}
Sleep(dwWaitTime);
if(!QueryServiceStatusEx(schService,SC_STATUS_PROCESS_INFO,(LPBYTE)&ssStatus,sizeof(SERVICE_STATUS_PROCESS),&dwByteNeeded))//假设服务没有
{
//报告进展的情况,再次查询
break;
}
if(ssStatus.dwCheckPoint > dwOld)//当报告的时间大于所规定的时间
{
dwStart = GetTickCount( );
dwOld = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount( ) - dwStart > ssStatus.dwWaitHint)//如果启动时间大于等待时间,失败(时间到)
{
break;
}
}
}
CloseServiceHandle(schService);
if(ssStatus.dwCurrentState == SERVICE_RUNNING)//判断状态
{
MessageBox(L"启动成功");
return -1;
}
else
{
MessageBox(L"启动失败");
return 0;
}




}


DWORD m_service::m_StopService(SC_HANDLE hSCM,LPTSTR szServiceName,BOOL fStop,DWORD dwTimeout)
{


SERVICE_STATUS_PROCESS ssp;
SERVICE_STATUS ss;
DWORD dwStartTime = GetTickCount( );
DWORD dwBytesNeeded;
SC_HANDLE hService = OpenService(hSCM,szServiceName,SERVICE_ALL_ACCESS);
if(!QueryServiceStatusEx(hService,SC_STATUS_PROCESS_INFO,(LPBYTE)&ssp,sizeof(SERVICE_STATUS_PROCESS),&dwBytesNeeded))
{
//判断是否停止
return GetLastError( );
}
if(ssp.dwCurrentState == SERVICE_STOP_PENDING)//如果是停止状态,只需等待
{
Sleep(ssp.dwWaitHint);
//循环查询状态的改变
if(!QueryServiceStatusEx(hService,SC_STATUS_PROCESS_INFO,(LPBYTE)&ssp,sizeof(SERVICE_STATUS_PROCESS),&dwBytesNeeded))
{
return GetLastError( );
}
if(ssp.dwCurrentState == SERVICE_STOP)
{
MessageBox(L"停止成功");
return ERROR_SUCCESS;
}
if(GetTickCount( ) - dwStartTime > dwTimeout)
{
return ERROR_TIMEOUT;
}
}
if(fStop)
{
//先结束依赖的服务
DWORD dwBytesNeeded;
DWORD dwCount;
LPENUM_SERVICE_STATUS lpDependcies = NULL;
ENUM_SERVICE_STATUS ess;
SC_HANDLE hDepService;
//使用0大小的buf,获取Buf的大小
if(!EnumDependentServices(hService,SERVICE_ACTIVE,lpDependcies,0,&dwBytesNeeded,&dwCount))
{
if(GetLastError( ) != ERROR_MORE_DATA)
{
//返回成功,说明没有依赖服务
return  GetLastError( );
}
lpDependcies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap( ),HEAP_ZERO_MEMORY,dwBytesNeeded);
//查看依赖服务的数据
if(!lpDependcies)
{
return GetLastError( );
}
_try{
//获得依赖服务
if(!EnumDependentServices(hService,SERVICE_ACTIVE,lpDependcies,dwBytesNeeded,&dwBytesNeeded,&dwCount))
{
return GetLastError( );
}
for(int i = 0; i < dwCount; i++)
{
ess = *(lpDependcies + i);
//打开服务
hDepService = OpenService(hSCM,ess.lpServiceName,SERVICE_STOP | SERVICE_QUERY_STATUS);
if(!hDepService)
{
return GetLastError( );
}
_try
{
//结束服务
if(!ControlService(hDepService,SERVICE_CONTROL_STOP,&ss))
{
return GetLastError( );
}
//等待服务结束
while(ss.dwCurrentState != SERVICE_STOPPED)
{
Sleep(ss.dwWaitHint);
if(!QueryServiceStatusEx(hDepService,SC_STATUS_PROCESS_INFO,(LPBYTE)&ssp,sizeof(SERVICE_STATUS_PROCESS),&dwBytesNeeded))
{
return GetLastError( );
}
if(ss.dwCurrentState == SERVICE_STOPPED)
{
break;
}
if(GetTickCount( ) - dwStartTime > dwTimeout)
{
return ERROR_TIMEOUT;
}
}
}
_finally
{
//关闭服务
CloseServiceHandle(hDepService);
}
}
}
_finally
{
//释放内存
HeapFree(GetProcessHeap( ),0,lpDependcies);
}
}
}
//所有的依赖服务已经关闭,结束指定服务
if(!ControlService(hService,SERVICE_STOPPED,&ss))
{
return GetLastError( );
}
while(ss.dwCurrentState != SERVICE_STOPPED)
{
Sleep(ss.dwWaitHint);
if(!QueryServiceStatusEx(hService,SC_STATUS_PROCESS_INFO,(LPBYTE)&ssp,sizeof(SERVICE_STATUS_PROCESS),&dwBytesNeeded))
{
return GetLastError( );
}
if(ss.dwCurrentState == SERVICE_STOPPED)
{
break;
}
if(GetTickCount( ) - dwStartTime > dwTimeout)
{
return ERROR_TIMEOUT;
}
}


return ERROR_SUCCESS;






}


//启动
void m_service::OnBnClickedButton1( )
{
// TODO:  在此添加控件通知处理程序代码
CString str1;
int nId;
//首先得到点击的位置
POSITION pos = MyList.GetFirstSelectedItemPosition( );
//得到行号,通过POSITION转化
nId = (int)MyList.GetNextSelectedItem(pos);
//得到列中的内容(0表示第一列,同理1,2,3...表示第二,三,四...列)
str1 = MyList.GetItemText(nId,0);
m_StartService(hSCM,(LPTSTR)(LPCTSTR)str1);//启动服务




}


//停止
void m_service::OnBnClickedButton2( )
{
// TODO:  在此添加控件通知处理程序代码
CString str1;
int nId;
//首先得到点击的位置
POSITION pos = MyList.GetFirstSelectedItemPosition( );
//得到行号,通过POSITION转化
nId = (int)MyList.GetNextSelectedItem(pos);
//得到列中的内容(0表示第一列,同理1,2,3...表示第二,三,四...列)
str1 = MyList.GetItemText(nId,0);
m_StopService(hSCM,(LPTSTR)(LPCTSTR)str1,TRUE,1000);
}



这篇关于MFC系统服务开启停止代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061778

相关文章

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

关于DNS域名解析服务

《关于DNS域名解析服务》:本文主要介绍关于DNS域名解析服务,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录DNS系统的作用及类型DNS使用的协议及端口号DNS系统的分布式数据结构DNS的分布式互联网解析库域名体系结构两种查询方式DNS服务器类型统计构建DNS域

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素