创建一个windows服务

Posted 小米渣的逆袭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建一个windows服务相关的知识,希望对你有一定的参考价值。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsvc.h>
#include <stdio.h>

#define SLEEP_TIME 5000
#define LOG_FILE L"C:\\\\Users\\\\wjr\\\\Desktop\\\\log\\\\service.log"
#define SERVICE_NAME    L"wjrtest"
#define SERVICE_DISPLAY_NAME L"我的测试服务"
#define SERVICE_DESCRIPTION	 L"我的第一个测试服务" 

SERVICE_STATUS    ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
SC_HANDLE scm;
SC_HANDLE scv;

void ServiceMain(int argc, LPWSTR* argv);
void ControlHandler(DWORD request);
void Log(const char* msg);
int startFunc();
void OnStart();
void OnCreate();
void OnDelete();
void OnStop();
void writeServiceDescription();


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

	SERVICE_TABLE_ENTRY ServiceTable[2] =
	
		 (LPWSTR)SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain ,
		 NULL,NULL 
	;
	Log("启动Main");
	if (argc == 2)
	
		if (!strcmp(argv[1], "-create"))
		
			OnCreate();
			return 0;
		
		else if (!strcmp(argv[1], "-delete"))
		
			OnDelete();
			return 0;
		
		else if (!strcmp(argv[1], "-start"))
		
			OnStart();
			return 0;
		
		else if (!strcmp(argv[1], "-stop"))
		
			OnStop();
			return 0;
		
		else
		
			Log("参数错误\\n");
			return 0;
		
	


	StartServiceCtrlDispatcher(ServiceTable);
	return 0;


void Log(const char* str)

	SYSTEMTIME time;
	GetLocalTime(&time);
	char buf[3000] =  0 ;	
	sprintf_s(buf, 3000, "%04d-%02d-%02d %02d:%02d:%02d [%lu] [%lu] %s\\r\\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond,GetCurrentProcessId(), GetCurrentThreadId(),str);

	FILE* fp = NULL;
	_wfopen_s(&fp, LOG_FILE, L"a+");
	if (fp == NULL)
	
		printf("error to open file: %d\\n", GetLastError());
		return;
	
	fprintf(fp, "%s", buf);
	fflush(fp);
	fclose(fp);


void ServiceMain(int argc, LPWSTR* argv)

	Log("ServiceMain");
	BOOL bRet;	
	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("服务器启动失败");
		return;
	
	//service status update
	ServiceStatus.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus(hStatus, &ServiceStatus);

	while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
			
		Log("I am runing");
		Sleep(5000);
	
	Log("程序退出");
	ServiceStatus.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(hStatus, &ServiceStatus);


int startFunc()

	MessageBox(NULL, L"startFunc", SERVICE_NAME, MB_OK);
	return 0;


void ControlHandler(DWORD request)

	//主要这个线程和ServiceMain不是一个线程
	switch (request)
	
	case SERVICE_CONTROL_STOP:
		Log("SERVICE_CONTROL_STOP");
		//标识正在停止
		ServiceStatus.dwWin32ExitCode = 0;
		ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
		SetServiceStatus(hStatus, &ServiceStatus);
		return;

	case SERVICE_CONTROL_SHUTDOWN:
		Log("SERVICE_CONTROL_SHUTDOWN");
		ServiceStatus.dwWin32ExitCode = 0;
		ServiceStatus.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(hStatus, &ServiceStatus);
		return;
	default:
		break;
	

	SetServiceStatus(hStatus, &ServiceStatus);


void OnCreate()

	WCHAR filename[MAX_PATH];
	DWORD dwErrorCode;
	GetModuleFileName(NULL, filename, MAX_PATH);
	Log("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_WIN32_OWN_PROCESS,
		SERVICE_AUTO_START, //自动启动服务
		SERVICE_ERROR_NORMAL,//忽略错误
		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;

	//注册表写入
	writeServiceDescription();


void writeServiceDescription()

	HKEY resultKey = NULL;
	WCHAR buf[1000] =  0 ;
	wsprintf(buf, L"SYSTEM\\\\CurrentControlSet\\\\Services\\\\%s", SERVICE_NAME);
	LSTATUS status = RegOpenKey(HKEY_LOCAL_MACHINE, buf, &resultKey);
	if (status != ERROR_SUCCESS)
	
		Log("注册表打开失败");
		return;
	
	int size = (int)wcslen(SERVICE_DESCRIPTION) * sizeof(WCHAR);
	status = RegSetValueEx(resultKey, L"Description", 0, REG_SZ, (const BYTE*)SERVICE_DESCRIPTION, size);
	if (status != ERROR_SUCCESS)
	
		Log("写入服务器描述失败");
	
	RegCloseKey(resultKey);



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
	Log("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
	
		printf("error to OpenSCManager\\n");
	
	scm = scv = NULL;
	printf("Start Success\\n");



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;

 

以上是关于创建一个windows服务的主要内容,如果未能解决你的问题,请参考以下文章

创建 Windows 服务的指南?

使用Topshelf创建Windows 服务

C#创建服务及使用程序自动安装服务,.NET创建一个即是可执行程序又是Windows服务的exe

C#创建一个Window服务

[翻译] 使用 .NET Core 3.0 创建一个 Windows 服务

C/C++ 创建windows系统服务程序