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);}
}

编译产物如下:

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

2.2 服务注册

MyService.exe /install

2.3  服务卸载

MyService.exe /uninstall

可以看到服务已经被删除

2.4 启动服务

net start MyService

2.5 关闭服务

net stop MyService

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

2.7 查看服务

方法一

services.msc

方法二:

电脑 - 右键管理

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
 

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

 C++之创建Windows系统服务_c++编写windows服务-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/124493.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web漏洞-PHP反序列化

目录 PHP反序列化序列化反序列化原理涉及技术利用危害CTF靶场 PHP反序列化 序列化 将对象转换成字符串 反序列化 相反&#xff0c;将字符串转换成对象。 数据格式的转换对象的序列化有利于对象的保存和传输&#xff0c;也可以让多个文件共享对象。 原理 未对用户输入的序列化字…

【Stm32-F407】Keil uVision5 的安装

文章内容如下&#xff1a; 1&#xff09;Keil uVision5 安装包的获取2&#xff09;Keil uVision5 的安装3&#xff09;Keil uVision5 中 Stm32-F407 芯片包的获取与安装4&#xff09;注册 Keil uVision5 1&#xff09;Keil uVision5 安装包的获取 Keil uVision5 安装包链接: h…

OpenCV报错:AttributeError: module ‘cv2.cv2‘ has no attribute ‘SIFT_create‘

报错位置&#xff1a; sift cv2.SIFT_create()报错原因&#xff1a;opencv将SIFT等算法整合到xfeatures2d集合里面了。 改为&#xff1a; sift cv2.xfeatures2d.SIFT_create()

sheng的学习笔记-【中文】【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第二周测验

课程1_第2周_测验题 目录&#xff1a;目录 第一题 1.神经元计算什么&#xff1f; A. 【  】神经元计算激活函数后&#xff0c;再计算线性函数&#xff08;zWxb&#xff09; B. 【  】神经元计算一个线性函数&#xff08;zWxb&#xff09;&#xff0c;然后接一个激活函数…

打字速度测试,生成您的打字速度证书?

趁着十一国庆之际&#xff0c;开发完成了打字侠的速度测试功能。我自己的打字速度约为56字/分钟&#xff0c;算是盲打中速度比较快的。下面是我的打字荣誉证书&#xff0c;欢迎大家免费测试自己的打字速度。 你也想来测试一下自己的打字速度吗&#xff1f; 打字侠速度测试地址…

一键智能视频编辑与视频修复算法——ProPainter源码解析与部署

前言 视频编辑和修复确实是随着电子产品的普及变得越来越重要的技能。有许多视频编辑工具可以帮助人们轻松完成这些任务如&#xff1a;Adobe Premiere Pro&#xff0c;Final Cut Pro X&#xff0c;Davinci Resolve&#xff0c;HitFilm Express&#xff0c;它们都提供一些视频修…

OpenCV 13(模版匹配和霍夫变换)

一、模版匹配 所谓的模板匹配&#xff0c;就是在给定的图片中查找和模板最相似的区域&#xff0c;该算法的输入包括模板和图片&#xff0c;整个任务的思路就是按照滑窗的思路不断的移动模板图片&#xff0c;计算其与图像中对应区域的匹配度&#xff0c;最终将匹配度最高的区域…

Qt扩展-QCustomPlot绘图基础概述

QCustomPlot绘图基础概述 一、概述二、改变外观1. Graph 类型2. Axis 坐标轴3. 网格 三、案例1. 简单布局两个图2. 绘图与多个轴和更先进的样式3. 绘制日期和时间数据 四、其他Graph&#xff1a;曲线&#xff0c;条形图&#xff0c;统计框图&#xff0c;… 一、概述 本教程使用…

【C语言】函数的定义、传参与调用(二)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C语言初步学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a; 1. 函数的嵌套调用 1.1 什么是嵌套调用 1.2 基础实现 1.3 调用流程解析 2. 函数的链式访问 2.1 …

《深度不确定条件下的决策:从理论到实践》PDF

制定未来计划时需要预测变化&#xff0c;尤其是制定长期计划或针对罕见事件的计划时。当这些变化存在高度不确定性的时候&#xff0c;这种预期就变得越来越困难。 今天给大家介绍的这本《深度不确定条件下的决策&#xff1a;从理论到实践》正是解决以上问题的良方。完整书籍文…

聊聊分布式架构——Http到Https

目录 HTTP通信协议 请求报文 响应报文 持久连接 状态管理 HTTPS通信协议 安全的HTTPS HTTP到HTTPS的演变 对称加密 非对称加密 混合加密机制 证书机构 SSL到底是什么 HTTPS是身披SSL外壳的HTTP HTTP通信协议 一次HTTP请求的通信流程&#xff1a;客户端浏览器通过…

GET 和 POST的区别

GET 和 POST 是 HTTP 请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过 WEB 开发的人都能说出一二。 最直观的区别就是 GET 把参数包含在 URL 中&#xff0c;POST 通过 request body 传递参数。 你可能自己写过无数个 GET 和 POST 请求&#xff0c;或者已经看…