windows service程序的入门范例(二)
一、 隔了一段时间,由于工作上,一些项目是使用Windows Service的方式来做的,虽然,我主要倾向于使用Linux 进行C++编码,但是没办法,接手人家的工作就是得学习怎么做这一类的事情。
闲话不多说,直接上代码,注释的非常清楚,可以直接拿去使用,VS2013下正常运行通过,我相信VS2008以上的都没问题。
二、 关键,在于理解到底该怎么使用 windows service的程序。
【答】:
(1)这类程序是一种套路,把下面代码的套路用上,然后就可以和普通的程序一样使用,没有任何区别。当然,我这两个文件没有把安装服务,卸载服务写进来,但是我把接口留好了,以后有机会再补上吧。
(2)套路就是:在指定的地方,例如本例中的业务逻辑指定入口——ServerProgram() ,写下自己要做的事情,一般是无限循环的,否则不需要做成service程序。
1.使用VS新建一个控制台的项目。
2.添加一个头文件testService.h,代码如下
#include <Windows.h>
#define FILE_PATH "C:\\log.txt" //信息输出文件
#define SERVICE_NAME TEXT("my_server") //服务名
SERVICE_STATUS g_SvcStatus; //服务状态
SERVICE_STATUS_HANDLE g_SvcStatusHandle; //服务状态句柄
HANDLE g_hSvcStopEvent = NULL;//服务停止句柄
void WINAPI ServiceMain(int argc, char** argv); //服务入口点
VOID WINAPI SvcCtrlHandler(DWORD); //SCM回调函数
VOID ReportSvcStatus(DWORD , DWORD , DWORD);
void ServerProgram(); //服务主程序
int WriteToLog(char* str); //输出信息到本地文件
//
3.在main()所在的文件,代码如下:
// testService.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "testService.h"
int _tmain(int argc, char* argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
return GetLastError();
}
if (argc == 1) {
//RunService();
}
else {
if (strcmp(argv[1], "install") == 0) {
//InstallService();
}
else if (strcmp(argv[1], "uninstall") == 0) {
//UninstallService();
}
}
return 0;
}
void WINAPI ServiceMain(int argc, char** argv)
{
// These SERVICE_STATUS members remain as set here
g_SvcStatus.dwServiceType = SERVICE_WIN32; //只有一个单独的服务
g_SvcStatus.dwCurrentState = SERVICE_START_PENDING;
g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; //指明服务接受何种控制
g_SvcStatus.dwWin32ExitCode = 0;
g_SvcStatus.dwServiceSpecificExitCode = 0;
g_SvcStatus.dwCheckPoint = 0;
g_SvcStatus.dwWaitHint = 0;
// Register the handler function for the service
g_SvcStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, SvcCtrlHandler);
if (!g_SvcStatusHandle)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
// TO_DO: Perform work until service stops.
ServerProgram(); //你需要的操作在此添加代码
}
VOID ReportSvcStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
// Fill in the SERVICE_STATUS structure.
g_SvcStatus.dwCurrentState = dwCurrentState;
g_SvcStatus.dwWin32ExitCode = dwWin32ExitCode;
g_SvcStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_START_PENDING)
g_SvcStatus.dwControlsAccepted = 0;
else g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED))
g_SvcStatus.dwCheckPoint = 0;
else g_SvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus(g_SvcStatusHandle, &g_SvcStatus);
}
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl)
{
// Handle the requested control code.
switch (dwCtrl)
{
case SERVICE_CONTROL_STOP:
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
return;
case SERVICE_ACCEPT_SHUTDOWN:
break;
default:
break;
}
ReportSvcStatus(g_SvcStatus.dwCurrentState, NO_ERROR, 0);
}
void ServerProgram()
{
while (1){
WriteToLog("success 123456");
Sleep(2000);
}
}
int WriteToLog(char* str)
{
FILE* pfile;
fopen_s(&pfile, FILE_PATH, "a+");
if (pfile == NULL)
{
return -1;
}
fprintf_s(pfile, "%s\n", str);
fclose(pfile);
return 0;
}
//
4.编译并生成解决方案即可。
5.剩下的步骤,就是安装服务,运行服务以及删除服务。可参考之前的博客windows service程序的入门范例(一)。
6.套路还是比较简单的,就是自己的业务逻辑要放到指定的地方去做和平时写代码有点不同罢了。
=============