WIN32服务程序(三):完整的服务程序实例

2026-02-08 13:53:49
admin

前面我们所讲的“服务程序”,更准确地说是服务控制程序,例如我们通过输入应用的路径,将一个应用程序添加到服务控制管理器。一个服务控制程序可以将一个程序添加到服务控制管理器中,并控制它的运行、停止和删除等。那么怎么避免手动添加的方式,直接将我们想要运行的代码添加到服务中呢?这需要我们建立一个完整的服务程序,要同时包括服务主程序和服务控制程序。

关于服务主程序

服务主程序包括一个main函数作为程序的标准入口,一个ServiceMain函数作为服务程序的入口,一个Handler函数实现服务启动,停止等功能,最后是一个MyWork函数,这里面可以写入我们想要运行的代码,也就是服务要实现的功能。

我们来看一个程序,该程序实现的功能是在服务运行期间,循环执行MessageBox函数;可以在cmd上运行应用程序,给其传递参数,实现对于服务的控制。这个程序在逻辑的实现上比较简单,某些函数可以直接查看msdn文档,附上链接地址https://technet.microsoft.com/zh-cn/library/

#define WIN32_LEAN_AND_MEAN

#include

#include

#include

#define SLEEP_TIME 5000

#define LOG_FILE "c:\\MemoryWatch.txt"

#define SERVICE_NAME "servitest"

#define SERVICE_DESC "test"

#define SERVICE_DISPLAY_NAME "test"

SERVICE_STATUS ServiceStatus;

SERVICE_STATUS_HANDLE hStatus;

SC_HANDLE scm;

SC_HANDLE scv;

void ServiceMain(int argc, char** argv);

void ControlHandler(DWORD request);

void Log(char* filename);

int startFunc();

void OnStart();

void OnCreate();

void OnDelete();

void OnStop();

int main(int argc, char* argv[])

{

// Service Name:MemoryStatus

// Service Handle Function: ServiceMain()

SERVICE_TABLE_ENTRY ServiceTable[2] =

{

{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },

{ NULL,NULL}

};

if(argc == 2)

{

if(!stricmp(argv[1],"-create"))

{

OnCreate();

return 0;

}

else if(!stricmp(argv[1],"-delete"))

{

OnDelete();

return 0;

}

else if(!stricmp(argv[1],"-start"))

{

OnStart();

return 0;

}

else if(!stricmp(argv[1],"-stop"))

{

OnStop();

return 0;

}

else

{

printf("invailid parameter\n");

return 0;

}

}

StartServiceCtrlDispatcher(ServiceTable);

return 0;

}

void Log(char* str)

{

FILE* fp = fopen(LOG_FILE, "a+");

if(fp == NULL)

{

printf("error to open file: %d\n", GetLastError());

return;

}

fprintf(fp, "%s\n", str);

fflush(fp);

fclose(fp);

}

void ServiceMain(int argc, char** argv)

{

BOOL bRet;

int result;

bRet = TRUE;

ServiceStatus.dwWin32ExitCode = 0;

ServiceStatus.dwCheckPoint = 0;

ServiceStatus.dwWaitHint = 0;

ServiceStatus.dwServiceType = SERVICE_WIN32;

ServiceStatus.dwCurrentState = SERVICE_START_PENDING;

ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;

ServiceStatus.dwServiceSpecificExitCode = 0;

hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, (LPHANDLER_FUNCTION)ControlHandler);

if(hStatus == (SERVICE_STATUS_HANDLE)0)

{

// log failed

return;

}

//service status update

ServiceStatus.dwCurrentState = SERVICE_RUNNING;

SetServiceStatus(hStatus, &ServiceStatus);

while(ServiceStatus.dwCurrentState == SERVICE_RUNNING)

{

result = startFunc();

if(result)

{

ServiceStatus.dwCurrentState = SERVICE_STOPPED;

ServiceStatus.dwWin32ExitCode = -1;

SetServiceStatus(hStatus, &ServiceStatus);

return;

}

}

}

int startFunc()

{

MessageBox(NULL, "startFunc", SERVICE_NAME, MB_OK);

return 0;

}

void ControlHandler(DWORD request)

{

switch(request)

{

case SERVICE_CONTROL_STOP:

Log("Monitoring stopped.");

ServiceStatus.dwWin32ExitCode = 0;

ServiceStatus.dwCurrentState = SERVICE_STOPPED;

SetServiceStatus (hStatus, &ServiceStatus);

return;

case SERVICE_CONTROL_SHUTDOWN:

Log("Monitoring stopped.");

ServiceStatus.dwWin32ExitCode = 0;

ServiceStatus.dwCurrentState = SERVICE_STOPPED;

SetServiceStatus (hStatus, &ServiceStatus);

return;

default:

break;

}

SetServiceStatus (hStatus, &ServiceStatus);

}

void OnCreate()

{

char filename[MAX_PATH];

DWORD dwErrorCode;

GetModuleFileName(NULL, filename, MAX_PATH);

printf("Creating Service .... ");

scm = OpenSCManager(0/*localhost*/,

NULL/*SERVICES_ACTIVE_DATABASE*/,

SC_MANAGER_ALL_ACCESS/*ACCESS*/);

if (scm == NULL)

{

printf("OpenSCManager error:%d\n", GetLastError());

return;

}

scv = CreateService(scm,//句柄

SERVICE_NAME,//服务开始名

SERVICE_DISPLAY_NAME,//显示服务名

SERVICE_ALL_ACCESS, //服务访问类型

SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,//服务类型

SERVICE_AUTO_START, //自动启动服务

SERVICE_ERROR_IGNORE,//忽略错误

filename,//启动的文件名

NULL,//name of load ordering group (载入组名)

NULL,//标签标识符

NULL,//相关性数组名

NULL,//帐户(当前)

NULL); //密码(当前)

if (scv == NULL)

{

dwErrorCode = GetLastError();

if(dwErrorCode!=ERROR_SERVICE_EXISTS)

{

printf("Failure !\n");

CloseServiceHandle(scm);

return ;

}

else

{

printf("already Exists !\n");

}

}

else

{

printf("Success !\n");

CloseServiceHandle(scv);

}

CloseServiceHandle(scm);

scm = scv = NULL;

}

void OnDelete()

{

scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if (scm!=NULL)

{

scv=OpenService(scm,SERVICE_NAME,SERVICE_ALL_ACCESS);

if (scv != NULL)

{

QueryServiceStatus(scv,&ServiceStatus);

if (ServiceStatus.dwCurrentState==SERVICE_RUNNING)

{

ControlService(scv,SERVICE_CONTROL_STOP,&ServiceStatus);

}

DeleteService(scv);

CloseServiceHandle(scv);

}

CloseServiceHandle(scm);

}

scm = scv = NULL;

}

void OnStart()

{

DWORD dwErrorCode;

//Starting Service

printf("Starting Service .... ");

scm = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if(scm != NULL)

{

scv = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);

if (scv != NULL)

{

if(StartService(scv, 0, NULL)==0)

{

dwErrorCode = GetLastError();

if(dwErrorCode == ERROR_SERVICE_ALREADY_RUNNING)

{

printf("already Running !\n");

CloseServiceHandle(scv);

CloseServiceHandle(scm);

return ;

}

}

else

{

printf("Pending ... ");

}

//wait until the servics started

while(QueryServiceStatus(scv,&ServiceStatus)!=0)

{

if(ServiceStatus.dwCurrentState == SERVICE_START_PENDING)

{

Sleep(100);

}

else

{

break;

}

}

CloseServiceHandle(scv);

}

else

{

//error to OpenService

printf("error to OpenService\n");

}

CloseServiceHandle(scm);

}

else

{

//fail to OpenSCManager

}

/*

if(InstallServiceStatus.dwCurrentState != SERVICE_RUNNING)

{

printf("Failure !\n");

}

else

{

printf("Success !\nDumping Description to Registry...\n");

RegOpenKeyEx(HKEY_LOCAL_MACHINE,

"SYSTEM\\CurrentControlSet\\Services\\NtBoot",

0,

KEY_ALL_ACCESS,

&hkResult);

RegSetValueEx(hkResult,

"Description",

0,

REG_SZ,

(unsigned char *)"Driver Booting Service",

23);

RegCloseKey(hkResult);

}

CloseServiceHandle(schSCManager);

CloseServiceHandle(schService);

}//

*/

scm = scv = NULL;

}

void OnStop()

{

scm = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if(scm != NULL)

{

scv = OpenService(scm,SERVICE_NAME,SERVICE_STOP | SERVICE_QUERY_STATUS);

if (scv!=NULL)

{

QueryServiceStatus(scv,&ServiceStatus);

if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)

{

ControlService(scv,SERVICE_CONTROL_STOP,&ServiceStatus);

}

CloseServiceHandle(scv);

}

CloseServiceHandle(scm);

}

scm = scv = NULL;

}

程序编译好之后,运行cmd。我编译好的程序的完整路径是 C:\hi\Debug\hi.exe

执行 C:\hi\Debug\hi.exe -create创建服务

执行C:\hi\Debug\hi.exe -start 启动服务

……

在c盘MemoryWatch.txt有日志文件

Copyright © 2088 疾空激战活动站_射击游戏专题_枪械测评 All Rights Reserved.
友情链接