创建一个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:\\\\MemoryWatch.txt"
#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, char** argv);
void ControlHandler(DWORD request);
void Log(char* filename);
int startFunc();
void OnStart();
void OnCreate();
void OnDelete();
void OnStop();
void writeServiceDescription();

int main(int argc, char* argv[])
{
	SERVICE_TABLE_ENTRY ServiceTable[2] =
	{
		{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
		{ NULL,NULL }
	};
	printf("启动main\\r\\n");
	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
		{
			printf("invailid parameter\\n");
			return 0;
		}
	}


	StartServiceCtrlDispatcher(ServiceTable);
	return 0;
}

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

	while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
	{
		SYSTEMTIME time;
		GetLocalTime(&time);
		char buf[500] = { 0 };
		sprintf_s(buf, "%04d-%02d-%02d %02d: %02d:%02d I am runing", time.wYear, time.wMonth, time.wDay,time.wHour,time.wMinute,time.wSecond);
		Log(buf);
		Sleep(5000);
	}
}

int startFunc()
{
	MessageBox(NULL, L"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()
{
	WCHAR 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_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 = 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
	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
	{
		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服务的主要内容,如果未能解决你的问题,请参考以下文章

重新附加时片段创建/恢复重复视图

创建片段而不从 java 代码实例化它

很实用的JQuery代码片段(转)

导航组件防止在后按时重新创建片段

Delphi创建Windows快捷方式

Delphi创建Windows快捷方式