概述
Windows Service 程序编写方法
1.最简单的创建一个windows service程序
(1)新建一个win32控制台程序
(2)开始->运行->cmd,必须右键—>以管理员身份运行,此时进入dos命令提示符界面。
(3)输入 sc create test binPath= “D:Code_TestVS2012_testtest_consoletest_consoleReleasetest_console.exe”
图1
【注意】等号“=”后面,必须空一格,否则可能报错。
2.查看已经创建的服务
(1)开始->附件->运行->输入:services.msc
(2)进入系统的服务界面,可看到新创建的test服务。如下图2所示。
图2 查看服务
3.删除一个服务程序
进入命令提示符,输入指令:sc delete test
图3 删除一个服务
4.程序实例
4.1 概述
(1)由于service程序,不需要界面,我们在建工程的时候,建立一个控制台程序即可。常规的控制台程序如下图4所示。
图4 常见的控制台程序
(2)main函数的使用方法
由于windows服务不需要界面,所以大部分程序为win32控制台应用程序,所以程序主函数为main 而不是WinMain()。在主函数要做的主要工作就是两件事:
① 初始化一个SERVICE_TABLE_ENTRY 分派表结构体。
② 然后调用StartServiceCtrlDispatcher();这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线程运行分派表中对应于你的服务的ServiceMain()函数。ServiceMain()函数将在下面提到。
4.2 ServiceMain()函数用法
ServiceMain函数为void WINAPI ServiceMain(int argc, char** argv)格式的函数,函数名字可以任意定义。它的作用就是:将你需要执行的任务放到该函数中循环执行即可。
ServiceMain()就是服务程序的工作函数。
在ServiceMain执行你的任务前,需要给SERVICE_TABLE_ENTRY 分派表结构体进行赋值,注意由于此时服务还没有开始执行你的任务所以我们将服务的状态设置为SERVICE_START_PENDING,即正在初始化。
4.3 程序代码
以下代码,为全部的代码,可以直接运行,已经验证通过。
(1) 新建一个控制台程序
(2) 在main()所在的文件里面,使用以下代码
(3) 这个代码的功能,是每隔5s,打印一条日志到日志文件C:\log.txt里面。
##########################################################################
// test_console.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <windows.h>
using namespace std;
#define SLEEP_TIME 5000 //间隔时间
#define FILE_PATH "C:\log.txt" //信息输出文件
bool brun=false;
SERVICE_STATUS servicestatus;
SERVICE_STATUS_HANDLE hstatus;
int WriteToLog(char* str);
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI CtrlHandler(DWORD request);
int InitService();
int WriteToLog(char* str)
{
FILE* pfile;
fopen_s(&pfile,FILE_PATH,"a+");
if (pfile==NULL)
{
return -1;
}
fprintf_s(pfile,"%sn",str);
fclose(pfile);
return 0;
}
void WINAPI ServiceMain(int argc, char** argv)
{
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;//在本例中只接受系统关机和停止服务两种控制命令
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler(L"testservice", CtrlHandler);
if (hstatus==0)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
//向SCM 报告运行状态
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hstatus, &servicestatus);
//下面就开始任务循环了,你可以添加你自己希望服务做的工作
brun=true;
MEMORYSTATUS memstatus;
char str[100];
memset(str,'