Qt 之windows服务实现C++语言

一、前言

最近有个项目需要写一个服务,如下:

二、windows服务

其实我们写windows服务的时候用命令去安装,卸载服务非常不方便,手动去启动时候也麻烦,那么用QT写个界面比较科学。

三、核心代码

1、安装服务

int SktVideoServer::install()
{
	int iRet = 0;
	m_schRelSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (NULL == m_schRelSCManager)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("打开服务管理器失败"));
		return 1;
	}

	char szSktCurPath[MAX_PATH] = { 0 };
	iRet = SktGetPath(szSktCurPath, MAX_PATH);
	if (0 != iRet)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("获取不到当前路径"));
		return 2;
	}

	char szPathBuf[1024];
	sprintf_s(szPathBuf, 1024, "%s\\%s", szSktCurPath, SKT_REL_SVC_NAME);
	m_schRelService = CreateService(
		m_schRelSCManager,
		SKT_REL_SVC_DISP,
		"SC Skt Relay Service Engeine",
		SERVICE_ALL_ACCESS,
		SERVICE_WIN32_OWN_PROCESS,
		SERVICE_DEMAND_START,
		SERVICE_ERROR_NORMAL,
		szPathBuf,
		NULL, NULL, NULL, NULL, NULL);
	if (NULL == m_schRelService)
	{
		clear();
		ui.showLbl->setText(QString::fromLocal8Bit("安装服务失败"));
		return 3;
	}
	else {
		ui.showLbl->setText(QString::fromLocal8Bit("安装服务成功"));
	}

	clear();
	return iRet;
}

2、开启服务

int SktVideoServer::SktStartMediaServer()
{
	int iRet = 0;

	SERVICE_STATUS status;
	m_schRelSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);   // 打开服务控制管
	if (NULL == m_schRelSCManager)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("打开服务管理器失败"));
		return 1;
	}

	m_schRelService = OpenService(m_schRelSCManager, SKT_REL_SVC_DISP, SERVICE_ALL_ACCESS | DELETE);   // 获得服务句柄
	if (NULL == m_schRelService)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("获取服务句柄失败"));
		return 2;
	}

	QueryServiceStatus(m_schRelService, &status);				// 获得服务的当前状态
	if (status.dwCurrentState == SERVICE_STOPPED)			// 如果服务处于停止状态,则将其状态设置为启动状态
	{
		BOOL iRet = StartService(m_schRelService, 0, NULL);	//启动服务
		if (iRet == FALSE)
		{
			iRet = GetLastError();
			char szSktVal[256] = { 0 };
			sprintf_s(szSktVal, 256, "===>启动失败%d", iRet);
			ui.showLbl->setText(QString::fromLocal8Bit(szSktVal));
			return 3;
		}
		else {
			ui.showLbl->setText(QString::fromLocal8Bit("启动服务成功"));
		}
	}else if(status.dwCurrentState == SERVICE_RUNNING){
		ui.showLbl->setText(QString::fromLocal8Bit("服务已经启动"));
	}else {
		ui.showLbl->setText(QString::fromLocal8Bit("启动服务失败"));
		return 4;
	}

	clear();
	return iRet;
}

3、停止服务

int SktVideoServer::stop()
{
	int iRet = 0;
	SERVICE_STATUS status;
	m_schRelSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (NULL == m_schRelSCManager)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("打开服务管理器失败!"));
		return iRet;
	}

	m_schRelService = OpenService(m_schRelSCManager, SKT_REL_SVC_DISP, SERVICE_ALL_ACCESS | DELETE);   // 获得服务句柄
	if (NULL == m_schRelService)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("获取服务句柄失败!"));
		return iRet;
	}

	while (1)
	{
		QueryServiceStatus(m_schRelService, &status);  // 获得服务的当前状态
		if (status.dwCurrentState != SERVICE_STOPPED)   // 如果服务不处于停止状态,则将其状态设置为停止状态
		{
			BOOL bRet = ControlService(m_schRelService, SERVICE_CONTROL_STOP, &status);
			if (FALSE == bRet)
			{
				ui.showLbl->setText(QString::fromLocal8Bit("停止服务失败!"));
				clear();
				return iRet;
			}
		}

		if (status.dwCurrentState == SERVICE_STOPPED)
		{
			ui.showLbl->setText(QString::fromLocal8Bit("停止服务成功!"));
			break;
		}
	}

	clear();
	return iRet;
}

4、卸载服务

int SktVideoServer::uninstall()
{
	int iRet = 0;
	SERVICE_STATUS status;
	SC_HANDLE schSCManager = NULL;
	SC_HANDLE schService = NULL;

	m_schRelSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (NULL == m_schRelSCManager)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("打开服务管理器失败"));
		return iRet;
	}

	m_schRelService = OpenService(m_schRelSCManager, SKT_REL_SVC_DISP, SERVICE_ALL_ACCESS | DELETE);   // 获得服务句柄
	if (NULL == m_schRelService)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("获得服务句柄失败"));
		return iRet;
	}

	while (1)
	{
		QueryServiceStatus(m_schRelService, &status);  // 获得服务的当前状态
		if (status.dwCurrentState != SERVICE_STOPPED)   // 如果服务不处于停止状态,则将其状态设置为停止状态
		{
			ControlService(schService, SERVICE_CONTROL_STOP, &status);
		}

		if (status.dwCurrentState == SERVICE_STOPPED)
		{
			break;
		}
	}

	BOOL bRet = DeleteService(m_schRelService);    // 删除服务
	if (FALSE == bRet)
	{
		ui.showLbl->setText(QString::fromLocal8Bit("删除服务失败"));
		return iRet;
	}
	else {
		ui.showLbl->setText(QString::fromLocal8Bit("卸载服务成功"));
	}

	clear();
	return iRet;
}

5、服务程序

void CSktMainSvc::ServiceMain(int argc, char** argv)  
{  
	SktInitSvc();
	SktSetSvc();

	m_hStatus = ::RegisterServiceCtrlHandlerEx(SKT_MAIN_SVC_NAME, CtrlHandler, this);
	if (m_hStatus == (SERVICE_STATUS_HANDLE)0)
	{   
		return;  
	}  
 
	m_stServiceStatus.dwCurrentState = SERVICE_RUNNING;  
	SetServiceStatus (m_hStatus, &m_stServiceStatus);  

//	Sleep(15000);
	StartMainEng();

	DWORD dwRet = 0;
	HANDLE hWaitHandle[2] = {m_hStop, m_hCheck};
	DWORD dwMilliseconds = 1000 * 10;
//	DWORD dwMilliseconds = 1000 * 1;//1000为1秒
	while (true)
	{
		dwRet = WaitForMultipleObjects(2, hWaitHandle, FALSE, dwMilliseconds );
		if (WAIT_OBJECT_0 == dwRet)
		{
			if (SERVICE_STOPPED == m_stServiceStatus.dwCurrentState)
			{
				ResetEvent(m_hStop);
				break;	
			}
		}

		if (dwRet = (WAIT_OBJECT_0 + 1))
		{
			CheckSktMainEng();
			ResetEvent(m_hCheck);
		}
	}

	StopSktMainEng();

} 

四、总结

以上就是windows服务核写代码编写了,其实QT就只是几个按钮,如果要写的更好可以监测服务状态等等,源码已上传,欢迎大家下载讨论交流。

qt写的windows服务-C++文档类资源-CSDN下载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值