VC++创建windows服务程序

这篇具有很好参考价值的文章主要介绍了VC++创建windows服务程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.关于windows标准可执行程序和服务程序

2.服务相关整理

2.1 VC++编写服务

2.2 服务注册

2.3  服务卸载

2.4 启动服务

2.5 关闭服务

2.6 sc命令

2.7 查看服务

3.标准程序

3.1 后台方式运行标准程序

3.2 查找进程

3.3 终止进程


       以前经常在Linux下编写服务器程序,服务器程序大多都是以守护进程方式运行,并且很多都是要开机启动方式进行。最近工作需要编写跨平台的服务,所以就 想了解一下windows下服务开发,通过查询资料发现windows服务完全是另外一回事,windows没有linux那种以&方式运行服务器程序的方式,需要单独使用另外一套api来开发。

1.关于windows标准可执行程序和服务程序

Window 标准的exe可执行程序通常有一个用户界面,Console或GUI,通常由用户来启动或停止.
Windows服务是运行在windows后台指定用户下(默认System)的应用程序,它没有标准的UI界面,相比标准的EXE程序,Windows服务是在服务开始的时候创建,而在服务结束的时候销毁,而且可以设置服务是否与操作系统一起启动,一起关闭。
它支持三种方式:1)自动方式 2)手动方式 3)禁用 。
自动方式的时候,windows服务将在OS启动后自动启动运行,而手动方式则必须手工启动服务,禁用的情况下服务将不能被启动。另外标准的EXE默认使用的当前登录的用户,而windows服务则默认使用System用户,这在对系统资源访问的时候特别需要注意。
Windows Service 是主要用于服务器环境而长期运行的应用程序, 这类程序不需要有用户界面或者任何模拟输出。 任何的用户消息通常都是记录在Windows 事件日志里。Windows Service可以在操作系统启动的时候开始,一直在后台运行,当有需要时也可以手动启动,我们可以通过管理工具里面的服务进行统一管理。当系统启动完毕后,Windows服务并不需要通过登陆页面后才能启动,而我们启动一般的exe文件却要先登陆Windows后才能启动它。
Windows Service 是一种可随 Windows 操作系统启动而启动的,在后台运行的,通常不和用户产生交互的程序。它无法通过双击来运行,类似于 Unix 守护进程(daemon processes),当用户注销时它也不会停止。
Windows 服务由三部分组成:1.一个服务可执行文件;2.一个服务控制程序(SCP);3.服务控制管理器(SCM),
负责在 HKLM\SYSTEM\CurrentControlSet\Services 下创建服务键值。用户可通过 SCP 控制服务的启动、停止、暂停等,SCP 会通过 SCM 调用服务程序。服务程序、服务控制程序(SCP,service control program)和服务控制管理器(SCM,service control manager)组成了Windows服务。我们可以通过服务控制程序操纵服务控制管理器来配置、启动、暂停、停止服务程序。其中服务程序和服务控制程序可以由我们自己来编写扩展,而服务控制管理器(\windows\system32\servics.exe)则是操作系统内置的一个部件。         

重点说明:
Windows服务程序其实并不神秘,它只是遵循特定规则编写的一个程序。只要遵循这个特定的规则与服务控制管理器正确的交互,就可实现我们的服务程序。而我们只要能实现一个简单的服务程序,设计一个能处理复杂业务的服务也并非难事,因为从结构上看两者并没有太大的区别。
只要遵循与SCM交互的规则,设计服务程序与设计普通的应用程序几乎没什么区别。

2.服务相关整理

2.1 VC++编写服务

// MyService.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>

using namespace std;

/*
BOOL IsInstalled(); 
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);

TCHAR szServiceName[] = _T("MyService");
BOOL bInstall;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
DWORD dwThreadID;
SC_HANDLE hSCM;
SC_HANDLE hService;
*/

/*
OpenSCManager 用于打开服务控制管理器;
CreateService 用于创建服务;
OpenService用于打开已有的服务,返回该服务的句柄;
ControlService则用于控制已打开的服务状态,这里是让服务停止后才删除;
DeleteService 用于删除指定服务。


RegisterServiceCtrlHandler 注册服务控制
*/

//定义全局函数变量  
void Init();
BOOL IsInstalled();
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);

TCHAR szServiceName[] = _T("MyService");
BOOL bInstall;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
DWORD dwThreadID;

int APIENTRY _tWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPTSTR    lpCmdLine,
	int       nCmdShow)
{
	Init();
	dwThreadID = ::GetCurrentThreadId();
	SERVICE_TABLE_ENTRY st[] =
	{
		{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
		{ NULL, NULL }
	};

	if (_stricmp(lpCmdLine, "/install") == 0)
	{
		Install();
	}
	else if (_stricmp((LPCTSTR)lpCmdLine, "/uninstall") == 0)
	{
		Uninstall();
	}
	else
	{
		if (!::StartServiceCtrlDispatcher(st))
		{
			LogEvent(_T("Register Service Main Function Error!"));
		}
	}

	return 0;
}

//初始化
void Init()
{
	hServiceStatus = NULL;
	status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
	status.dwCurrentState = SERVICE_START_PENDING;
	status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	status.dwWin32ExitCode = 0;
	status.dwServiceSpecificExitCode = 0;
	status.dwCheckPoint = 0;
	status.dwWaitHint = 0;
}

//服务主函数,这在里进行控制对服务控制的注册
void WINAPI ServiceMain()
{
	status.dwCurrentState = SERVICE_START_PENDING;
	status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

	//注册服务控制  
	hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
	if (hServiceStatus == NULL)
	{
		LogEvent(_T("Handler not installed"));
		return;
	}
	SetServiceStatus(hServiceStatus, &status);

	status.dwWin32ExitCode = S_OK;
	status.dwCheckPoint = 0;
	status.dwWaitHint = 0;
	status.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus(hServiceStatus, &status);

	//模拟服务的运行。应用时将主要任务放于此即可  
	//可在此写上服务需要执行的代码,一般为死循环  
	while (1)
	{
		FILE *p;
		p = fopen("c:\\log.txt", "ab+");
		SYSTEMTIME st;
		GetSystemTime(&st);
		char time[100] = { 0 };
		_sntprintf(time, 100, "%4d-%02d-%02d %02d:%02d:%02d\r\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
		fwrite(time, strlen(time), 1, p);
		fclose(p);

		Sleep(1000);
	}
	status.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(hServiceStatus, &status);
}

//Description:          服务控制主函数,这里实现对服务的控制,  
//                      当在服务管理器上停止或其它操作时,将会运行此处代码  
void WINAPI ServiceStrl(DWORD dwOpcode)
{
	switch (dwOpcode)
	{
	case SERVICE_CONTROL_STOP:
		status.dwCheckPoint = 1;
		status.dwCurrentState = SERVICE_STOP_PENDING;
		SetServiceStatus(hServiceStatus, &status);
		Sleep(500);
		status.dwCheckPoint = 0;
		status.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(hServiceStatus, &status);

		PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);
		break;
	case SERVICE_CONTROL_PAUSE:
		break;
	case SERVICE_CONTROL_CONTINUE:
		break;
	case SERVICE_CONTROL_INTERROGATE:
		break;
	case SERVICE_CONTROL_SHUTDOWN:
		exit(0);
		break;
	default:
		LogEvent(_T("Bad service request"));
	}
}

//判断服务是否已经被安装
BOOL IsInstalled()
{
	BOOL bResult = FALSE;

	//打开服务控制管理器  
	SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if (hSCM != NULL)
	{
		//打开服务  
		SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
		if (hService != NULL)
		{
			bResult = TRUE;
			::CloseServiceHandle(hService);
		}
		::CloseServiceHandle(hSCM);
	}
	return bResult;
}

//安装服务函数
BOOL Install()
{
	//检测是否安装过
	if (IsInstalled())
		return TRUE;

	//打开服务控制管理器  
	SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (hSCM == NULL)
	{
		MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);
		return FALSE;
	}

	//获取程序目录
	TCHAR szFilePath[MAX_PATH];
	::GetModuleFileName(NULL, szFilePath, MAX_PATH);

	//创建服务  
	SC_HANDLE hService = ::CreateService(hSCM, szServiceName, szServiceName,
		SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
		szFilePath, NULL, NULL, _T(""), NULL, NULL);

	//检测创建是否成功
	if (hService == NULL)
	{
		::CloseServiceHandle(hSCM);
		MessageBox(NULL, _T("Couldn't create service"), szServiceName, MB_OK);
		return FALSE;
	}

	//释放资源
	::CloseServiceHandle(hService);
	::CloseServiceHandle(hSCM);
	return TRUE;
}

//删除服务函数
BOOL Uninstall()
{
	//检测是否安装过
	if (!IsInstalled())
		return TRUE;

	//打开服务控制管理器
	SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (hSCM == NULL)
	{
		MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);
		return FALSE;
	}

	//打开具体服务
	SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
	if (hService == NULL)
	{
		::CloseServiceHandle(hSCM);
		MessageBox(NULL, _T("Couldn't open service"), szServiceName, MB_OK);
		return FALSE;
	}

	//先停止服务
	SERVICE_STATUS status;
	::ControlService(hService, SERVICE_CONTROL_STOP, &status);

	//删除服务  
	BOOL bDelete = ::DeleteService(hService);
	::CloseServiceHandle(hService);
	::CloseServiceHandle(hSCM);

	if (bDelete)  return TRUE;
	LogEvent(_T("Service could not be deleted"));
	return FALSE;
}

//记录服务事件
void LogEvent(LPCTSTR pFormat, ...)
{
	TCHAR    chMsg[256];
	HANDLE  hEventSource;
	LPTSTR  lpszStrings[1];
	va_list pArg;

	va_start(pArg, pFormat);
	_vstprintf(chMsg, pFormat, pArg);
	va_end(pArg);

	lpszStrings[0] = chMsg;

	hEventSource = RegisterEventSource(NULL, szServiceName);
	if (hEventSource != NULL)
	{
		ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);
		DeregisterEventSource(hEventSource);
	}
}

编译产物如下:

vc编写windows服务程序,windows服务程序,VC++,windows,服务

服务程序本身也是PE格式的文件。

2.2 服务注册

MyService.exe /install

vc编写windows服务程序,windows服务程序,VC++,windows,服务

vc编写windows服务程序,windows服务程序,VC++,windows,服务

2.3  服务卸载

MyService.exe /uninstall

vc编写windows服务程序,windows服务程序,VC++,windows,服务

可以看到服务已经被删除

vc编写windows服务程序,windows服务程序,VC++,windows,服务

2.4 启动服务

net start MyService

vc编写windows服务程序,windows服务程序,VC++,windows,服务

vc编写windows服务程序,windows服务程序,VC++,windows,服务

2.5 关闭服务

net stop MyService

vc编写windows服务程序,windows服务程序,VC++,windows,服务

vc编写windows服务程序,windows服务程序,VC++,windows,服务

2.6 sc命令

sc命令可以用于管理系统服务、计划任务、系统日志等方面,是不可或缺的神器。

(1) 要查看系统服务列表
sc query state=all

(2) 启动或者停止服务
sc start 服务名
sc stop 服务名

(3) 查看服务属性
例如:以CSV格式输出服务的属性
sc query 服务名 /format:csv

(4) 创建服务
sc create HelloWorldService binPath= "D:\VC\vcDemo\Debug\helloworld.exe"

(5) 山存储服务 
sc delete HelloWorldService

实战演示

创建服务

sc create MyService binPath= "D:\VC\vcDemo\Debug\MyService.exe"

启动服务

sc start MyService

关闭服务

sc stop MyService

删除服务

sc delete MyService

vc编写windows服务程序,windows服务程序,VC++,windows,服务

2.7 查看服务

方法一

services.msc

vc编写windows服务程序,windows服务程序,VC++,windows,服务

方法二:

电脑 - 右键管理

vc编写windows服务程序,windows服务程序,VC++,windows,服务

3.标准程序

3.1 后台方式运行标准程序

@ECHO OFF
%1 start mshta vbscript:createobject("wscript.shell").run("""%~0"" ::",0)(window.close)&&exit
start /b helloworld.exe

3.2 查找进程

tasklist | findstr hello

3.3 终止进程

@ECHO OFF
taskkill /im helloworld.exe /f
 

微软官方关于服务主函数说明:

编写服务程序主函数 - Win32 apps | Microsoft Learn

关于Windows服务,发现一个写的比较好的博客:

 C++之创建Windows系统服务_c++编写windows服务-CSDN博客文章来源地址https://www.toymoban.com/news/detail-727797.html

到了这里,关于VC++创建windows服务程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 红队专题-从零开始VC++C/S远程控制软件RAT-MFC-远控介绍及界面编写

    红队专题-从零开始VC++C/S远程控制软件RAT-MFC-远控介绍及界面编写

    一起学习 代码审计、安全开发、web攻防、逆向等。。。 私信联系 主程序 可执行程序 服务端生成器 主机上线 服务端程序 和 服务 文件管理 CMD 进程 服务自启动 编写前 功能了解分析 界面 运行模式 主程序 主对话框 操作菜单 列表框 配置信息 多线程操作 非模式对话框 操作系

    2024年02月06日
    浏览(10)
  • 补齐 windows 运行库和运行环境(VC++、DirectX、.Net)

    安装一些应用时,可能会缺少各种库文件导致软件崩溃报错。缺少的主要有三类:vc++、directx、.net。 这是最基本的库。 下载链接: 最新受支持的 Visual C++ 可再发行程序包下载 DirectX(Direct eXtension)是由微软公司创建的多媒体编程接口。 简单来说这个是和图形图像有关的。启

    2024年02月15日
    浏览(15)
  • Qt6之调用Windows下vc生成的动态链接库dll

    Qt6之调用Windows下vc生成的动态链接库dll

    Qt是跨平台工具,显然能和windows的动态库一起使用。 在Windows操作系统上,库以文件的形式存在,并且可以分为动态链接库(DLL) 和静态链接库两种。动态链接库文控以.dll为后缀名,静态链接库文控以.lib为后缀名。不管是动态链接库还是静态链接库,都是向它们的调用者提供变

    2024年02月09日
    浏览(13)
  • Windows10使用OrbSlam3-VS2017-VC12版本

    Windows10使用OrbSlam3-VS2017-VC12版本

    OrbSlam3集成了IMU信息,可用以VIO融合重建。参考这哥们的地址,依据GitHub上的介绍git clone --recursive 之后编译即可 ORBSLAM3 Win10 VS2017 配置简明指南_滥觞LanShang的博客-CSDN博客_orbslam3 windows Git地址:GitHub - chanho-code/ORB-SLAM3forWindows: ORB-SLAM3 for Windows Platform 编译过程: 1.使用sourcetree

    2024年02月09日
    浏览(12)
  • 【C语言学习教程---1】VC++6.0的安装和创建简单C语言工程文件教程

    【C语言学习教程---1】VC++6.0的安装和创建简单C语言工程文件教程

    事物的难度远远低于对事物的恐惧 在学习C语言之前,首先需要安装编译器软件,学习完理论知识及时动手操作是才能印象深刻,切勿纸上谈兵,这里选择安装的是一款比较经典的并且运行相对比较稳定的VC++6.0软件。 把软件资源下载到电脑上并进行解压,下载地址: 链接:

    2024年02月08日
    浏览(12)
  • VC++判断Windows系统是Win7、Win8,还是Win10系统(附源码)

    VC++判断Windows系统是Win7、Win8,还是Win10系统(附源码)

    目录 1、系统API函数GetVersionEx已经被废弃,不能再使用了 2、不同版本的操作系统是如何区分的 3、调用API接口NetWkstaGetInfo,获取系统的版本号 4、代码示例 5、判断系统是32位还是64位的 VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...) https://blog.csdn.net/chenlycly

    2024年02月03日
    浏览(11)
  • Inno Setup打包winform、wpf程序可判断VC++和.net环境

    Inno Setup打包winform、wpf程序可判断VC++和.net环境

    官网链接: link 1、新建打包文件 2、填写 应用名称、版本号、公司名称、公司官网 3、选择安装路径 Custom是指定默认路径、Program Files folder是默认C盘根目录 4、选择程序启动exe文件 以及Addfolder选择全部运行文件 5、选择安装前显示文字 、安装中、安装后 这里我只选择了安装前

    2024年02月16日
    浏览(7)
  • VM安装程序出现问题:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序

    VM安装程序出现问题:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序

    VM安装程序出现问题 此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序。 ** 安装软件即可,然后重启!或者不重启也可以,再次安装vmware,如果失败再重启!

    2024年02月11日
    浏览(11)
  • VMWare安装报错:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序。

    VMWare安装报错:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序。

    方法总比困难多! 本人很长时间没有碰Linux了,今天就想着先装个虚拟机玩玩,但是安装VMWare的过程也遇到了一些问题,,所以将问题的解决方法总结了一下,仅供大家参考~ 问题一:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序

    2024年02月05日
    浏览(19)
  • VC9、VC10、VC11等等各对应什么版本的Visual Studio,以及含义

    MS VC++ 15.0 _MSC_VER = 1910 (Visual Studio 2017) MS VC++ 14.0 _MSC_VER = 1900 (Visual Studio 2015) MS VC++ 12.0 _MSC_VER = 1800 (VisualStudio 2013) MS VC++ 11.0 _MSC_VER = 1700 (VisualStudio 2012) MS VC++ 10.0 _MSC_VER = 1600(VisualStudio 2010) MS VC++ 9.0 _MSC_VER = 1500(VisualStudio 2008) MS VC++ 8.0 _MSC_VER = 1400(VisualStudio 2005) MS VC++ 7.1 _MSC_VER

    2024年02月13日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包