windows服务程序一
Windows 服务程序简介:
int main(void)
return 0; }
SERVICE_TABLE_ENTRYA 结构体:
typedef struct _SERVICE_TABLE_ENTRYA {LPSTR lpServiceName; // 服务名称。LPSERVICE_MAIN_FUNCTIONA lpServiceProc; // 服务入口函数。 } SERVICE_TABLE_ENTRYA, *LPSERVICE_TABLE_ENTRYA;
StartServiceCtrlDispatcher() 介绍 :
功能:连接程序主线程到服务控制管理程序。
BOOL StartServiceCtrlDispatcher(CONST SERVICE_TABLE_ENTRYA *lpServiceStartTable // SERVICE_TABLE_ENTRYA 结构体变量。 );
返回值:非零表示成功,零表示失败。
ServiceMain是服务的入口点,它运行在一个单独的线程中,主要是为注册控制处理器服务, RegisterServiceCtrlHandler(strServiceName, (LPHANDLER_FUNCTION)ServiceCtrlHandler)。它指示控制分配器调用ServiceCtrlHandler()来处理SCM的请求,注册完成后将返回一个句柄,通过调用SetServiceStatus,用这个句柄和SERVICE_STATUS向SCM报告服务状态。它创建一个线程来运行我们的服务函数,ServiceThread()完成后返回ServiceMain(),ServiceMain()调用 WaitForSingleObject()。
编写控制处理器ServiceCtrlHandler,接受来自SCM的请求并作出反应,请求一般是下面几个值:
停止服务:SERVICE_CONTROL_STOP
暂停服务:SERVICE_CONTROL_PAUSE
恢复被暂停的服务:SERVICE_CONTROL_CONTINUE
MyWork,一个运行我们自己任务的线程,由ServiceMain()打开,执行我们的任务。
典型代码如下:
// SERVICE_STATUS ServiceStatus; //这段代码应声明为全局变量,因多处使用。// SERVICE_STATUS_HANDLE hStatus; //这段代码应声明为全局变量,因多处使用。void WINAPI
// 这个通知 SCM 服务接收哪个域。本例包含 停止,暂停和继续,关机等命令。ServiceStatus.dwWin32ExitCode = 0; // 这个域在终止服务并报告细节时很有用。下面这四个值一般不用关心,通常设置为 0。ServiceStatus.dwCheckPoint = 0; // 用来报告它当前的事件进展情况的。ServiceStatus.dwServiceSpecificExitCode = 0; // 这个域在终止服务并报告细节时也很有用。ServiceStatus.dwWaitHint = 0; // 根据初始化过程的长短而定。// 注册控制函数。hStatus = RegisterServiceCtrlHandler("ServiceName", // 注册服务控制程序,注册成功后将会返回一个服务状态句柄。(LPHANDLER_FUNCTION)ServiceHandler); // ServiceHandle 是服务控制程序。类似与 Windows 应用程序的窗口过程。if (!hStatus)
{
printf("Register Service Error!\n");
system("pause");return;
}
SetServiceStatus(hStatus, &ServiceStatus); // 设置服务状态。通过调用 SetServiceStatus 函数,向 SCM 报告服务的状态。
if (GetLastError != NO_ERROR) // 返回调用线程最近的错误代码值,检查是否出错。{// 如果出错,将其重设为停止状态。ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;SetServiceStatus(hStatus, &ServiceStatus);
printf("Start Error!\n");
system("pause"); return;}
// 没有错误就继续运行。
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus, &ServiceStatus);
// 创建线程执行特定功能
HANDLE hThread = CreateThread(NULL, 0, MyWork, NULL, 0, NULL); // MyWOrk 是特定功能的函数,如后门程序。
if(hThread = NULL)
return; }
SERVICE_STATUS 结构体:
typedef struct _SERVICE_STATUS { DWORD dwServiceType; // 服务类型。DWORD dwCurrentState; // 服务的当前状态。 DWORD dwControlsAccepted; // 服务在其处理函数中接受和处理的控制代码。DWORD dwWin32ExitCode; // 服务用于报告启动或停止时发生错误的错误代码。DWORD dwServiceSpecificExitCode; // 服务在启动或停止时发生错误时返回的错误代码。DWORD dwCheckPoint; // 服务在长时间启动、停止、暂停或继续操作期间定期递增以报告其进度的检查点值。DWORD dwWaitHint; // 将要进行 开始、停止、暂停或继续服务 操作所需的估计时间 (以毫秒为单位)。 } SERVICE_STATUS, *LPSERVICE_STATUS;
dwServiceType 的值:(可组合)
值 | 含义 |
SERVICE_FILE_SYSTEM_DRIVER | 该服务是一个文件系统驱动程序 |
SERVICE_KERNEL_DRIVER | 该服务是一个设备驱动程序 |
SERVICE_WIN32_OWN_PROCESS | 服务在自己的进程中运行(通常使用这个) |
SERVICE_USER_OWN_PROCESS | 该服务在登录用户帐户下在其自己的进程中运行 |
dwCurrentState 的值:
值 | 含义 |
SERVICE_CONTINUE_PENDING | 服务处于从暂停状态恢复的过程中 |
SERVICE_PAUSE_PENDING | 服务正在暂停过程中,但还有没完全进入暂停状态 |
SERVICE_PAUSED | 服务已经暂停了 |
SERVICE_RUNNING | 服务正在运行了 |
SERVICE_START_PENDING | 服务在启动过程中,但还没有准备好对请求进行响应 |
SERVICE_STOP_PENDING | 服务正在停止过程中,但还没有完全进入停止状态 |
SERVICE_STOPPED | 服务已经停止了 |
dwControlsAccepted 的值: (可组合)
值 | 含义 |
---|---|
SERVICE_ACCEPT_NETBINDCHANGE | 该服务是一个网络组件,并且能够在服务在服务不重启的情况下,改变其所网络接收的绑定,接收SERVICE_CONTROL_NETBINDADD、SERVICE_CONTROL_NETBINDREMOVE、SERVICE_CONTROL_NETBINDENABLE、SERVICE_CONTROL_NETBINDDISABLE 的通知 |
SERVICE_ACCEPT_PARAMCHANGE | 服务在不重启的情况下能够重新读取其配置参数,接收 SERVICE_CONTROL_PARAMCHANGE 通知 |
SERVICE_ACCEPT_PAUSE_CONTINUE | 服务支持暂停和重启,服务能够接收到 SERVICE_CONTROL_PAUSE 和SERVICE_CONTROL_CONTINUE的通知 |
SERVICE_ACCEPT_PRESHUTDOWN | 系统在关闭前,能够收到系统的 SERVICE_CONTROL_PRESHUTDOWN 通知,用来处理一些关闭前的清理,xp之前不支持此控制码 |
SERVICE_ACCEPT_SHUTDOWN | 能够接收系统退出时的 SERVICE_CONTROL_SHUTDOWN 的通知,以便处理一些回收 |
SERVICE_ACCEPT_STOP | 能够接收 SERVICE_CONTROL_STOP 的通知来处理一些回收任务 |
功能:更新服务控制管理器调用服务的状态信息。
函数原型:BOOL SetServiceStatus(
SERVICE_STATUS_HANDLE hServiceStatus, //服务状态信息结构的句柄, 由 RegisterServiceCtrlHandler() 返回。
LPSERVICE_STATUS lpServiceStatus // 指向 SERVICE_STATUS 结构的指针包含呼叫服务的最新状态信息。
);
返回值:非零表示成功,零表示失败。
功能:注册一个函数以处理服务控制请求。
函数原型:SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(
LPCSTR lpServiceName, //调用线程运行的服务的名称, 即在 CreateService() 中指定的服务控制程序的服务名称。
LPHANDLER_FUNCTION lpHandlerProc // 指向要注册的处理程序的函数。
);
返回值:如果函数成功, 则返回值为服务状态句柄。如果函数失败, 返回值为零。
CreateThread() 介绍:
功能:该函数在 主线程 的基础上创建一个新线程。线程 终止运行后,
线程对象仍然在系统中,必须通过 CloseHandle() 来关闭该线程对象。
函数原型:HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
参数:
lpThreadAttributes
指向 SECURITY_ATTRIBUTES 结构的指针, 它确定返回的句柄是否可以由子进程继承。
如果 lpThreadAttributes 为 NULL, 则无法继承句柄。
dwStackSize
堆栈的初始大小 (以字节为单位)。系统将此值舍入到最近的页面。
如果此参数为零, 则新线程将使用可执行文件的默认大小。
lpStartAddress
指向要由线程执行的应用程序定义的函数。此指针表示线程的起始地址。
lpParameter
指向要传递给线程的变量的指针。
dwCreationFlags
控制线程创建的标志。通常情况下为 0。
lpThreadId
指向接收线程标识符的变量的指针。如果此参数为 NULL, 则不返回线程标识符。
返回值:如果函数成功, 则返回值是新线程的句柄。如果函数失败, 返回值为 NULL。
ServiceHandle() 服务控制函数,典型代码如下:
void WINAPI ServiceHandler(DWORD fdwControl) {switch (fdwControl){case SERVICE_CONTROL_PAUSE:ServiceStatus.dwCurrentState = SERVICE_PAUSED;break;case SERVICE_CONTROL_CONTINUE:ServiceStatus.dwCurrentState = SERVICE_RUNNING;break;case SERVICE_CONTROL_STOP:case SERVICE_CONTROL_SHUTDOWN:ServiceStatus.dwCurrentState = SERVICE_STOPPED;ServiceStatus.dwCheckPoint = 0;ServiceStatus.dwWaitHint = 0;SetServiceStatus(hStatus, &ServiceStatus);return; default:break;}SetServiceStatus(hStatus, &ServiceStatus); // 重设服务状态。return; }
入门代码如下:(目前的代码仍然不能当做服务来运行,还需要 SCM 进行安装)
#include<stdio.h> #include<Windows.h> SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus; void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv); void WINAPI ServiceHandler(DWORD fdwControl);DWORD WINAPI MyWork(LPVOID lpParam); int main(void) {SERVICE_TABLE_ENTRY ServTable[2];ServTable[0].lpServiceName = (LPSTR)"Test";ServTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;ServTable[1].lpServiceName = NULL;ServTable[1].lpServiceProc = NULL;StartServiceCtrlDispatcher(ServTable);return 0; }
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(“ServiceName”,
(LPHANDLER_FUNCTION)ServiceHandler);
if (!hStatus)
{
printf(“Register Service Error!\n”);
system(“pause”);
return;
}
SetServiceStatus(hStatus, &ServiceStatus);
if (GetLastError() != NO_ERROR)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus, &ServiceStatus);
printf(“Start Service Error!\n”);
system(“pause”);
return;
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus, &ServiceStatus);
// 从这里开始可以放入你想服务为你所做的事情。
HANDLE hThread = CreateThread(NULL, 0, MyWork, NULL, 0, NULL);
if(hThread = NULL)
return;
}
void WINAPI ServiceHandler(DWORD fdwControl)
{
switch (fdwControl)
{
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus, &ServiceStatus);
return;
default:
break;
}
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
DWORD WINAPI MyWork(LPVOID lpParam)
{
return 0;
}
windows服务程序一相关推荐
- 用Visual C#创建Windows服务程序
一.Windows服务介绍: Windows服务以前被称作NT服务,是一些运行在Windows NT.Windows 2000和Windows XP等操作系统下用户环境以外的程序.在以前,编写Wind ...
- c语言编写系统服务程序,C语言Windows服务程序编写-ServiceMain
C语言编写的Windows服务程序,可以类比Linux/Unix环境下的daemon进程. 一下是VS2010环境下的demo: // windows_service.cpp : 定义控制台应用程序的 ...
- C#Windows服务程序安装常见问题解决方法
C#Windows服务程序安装是如何的呢?让我们开始吧: C#Windows服务程序安装1. 在服务程序的是设计窗体中,点击右键"添加安装程序",添加服务安装程序.否则,安装时会出 ...
- Visual C#创建Windows服务程序
转自:http://www.vchome.net/dotnet/dotnetdocs/dotnet38.htm 一.Windows服务介绍: Windows服务以前被称作NT服务,是一些运行在Wind ...
- 编写一个Windows服务程序,定时从数据库中拿出记录发送邮件
前言:编写一个Windows服务程序,定时从数据库中拿出记录发送邮件. 测试环境:Visual Studio 2005 SP1.Windows Server 2003 SP2 一.新建项目 打开VS2 ...
- Windows服务程序时钟调用
1 大概思路 设计服务程序 创建服务 安装必备组件 编写Service1 运行效果 2 设计服务程序 创建服务程序,通过添加System.Timers时钟进行定时向Wecome ...
- C语言编写Windows服务程序
C语言编写Windows服务程序 原文:C语言编写Windows服务程序 #include <Windows.h> #include <stdio.h>#define SLEE ...
- Windows 服务程序编写
摘要:几乎所有的操作系统在启动的时候都会启动一些不需要与用户交互的进程,这些进程在Windows中就被称作服务.它由服务程序.服务控制程序(SCP,service control program)和服 ...
- 多线程、方便扩展的Windows服务程序
多线程.方便扩展的Windows服务程序 吴剑 2012-06-02 原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian/ 前言 在项目应用中经常会碰到定时调度的 ...
- idea创建三种应用程序的方法:springboot,控制台程序,windows服务程序
springboot项目 控制台程序 windows服务程序 环境:idea 2017 + Maven 3.3.9+jdk 1.8 一.springboot项目 创建过程依次如下图所示: 至此一个简单 ...
最新文章
- 《Linux企业应用案例精解》一书已由清华大学出版社出版
- Session与request的使用
- SQL Server索引进阶第六篇:书签
- DebugView输出调试信息
- 绘制矩形php,PHP_php绘制一个矩形的方法,本文实例讲述了php绘制一个矩 - phpStudy...
- 黑客高手是这样上网的!Vimer是如何用快捷键浏览网页的?
- 读取CSV文件并将值存储到数组中
- python3之udp
- jQuery Deferred对象
- 最新StrongShop跨境电商系统源码+支持多语言
- pe中怎么卸载服务器系统更新,方法四: 使用专用工具卸载系统更新补丁(和方法三类同...
- C语言——输入两个正整数m和n,求其最大公约数和最小公倍数
- 游戏服务器——登陆服
- DTS北洋曳舞社网站开发手记
- 女生嘴唇怎么画?写实厚涂的女生嘴唇绘画技巧
- Wireshark - 【学习笔记】(Ubuntu18.04)、协议分析(IP、ARP、ICMP、DNS、UDP、TCP、DHCP、HTTP、HTTPS、FTP、Telnet)
- 超市商品管理系统(c语言)
- 自动化测试框架之DDT-数据驱动
- 在线伪原创代写工具文章生成器
- STM32F103的时钟
热门文章
- 7-1 厘米换算英尺英寸(15 分)
- 【AI实战】手把手教你深度学习文字识别(文字检测篇:基于MSER, CTPN, SegLink, EAST等方法)...
- 计算机科学与技术专业实践范文,计算机科学与技术专业毕业实习报告范文.docx...
- 日本测试人工智能破案,“机械战警”渐行渐近
- ActiveX控件的注册和反注册
- ubuntu插件配置
- 定时任务(三)动态配置定时任务
- element中设置5栏布局
- python多台电脑聊天室_python的多人多功能聊天室
- 嵌入式系统软件开发环境