前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Windows服务编程

Windows服务编程

作者头像
用户1423082
发布2024-12-31 18:27:24
发布2024-12-31 18:27:24
6900
代码可运行
举报
文章被收录于专栏:giantbranch's bloggiantbranch's blog
运行总次数:0
代码可运行

我们看到有什么360主动防御服务,Google更新服务等,我们也写个简单的服务吧

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <windows.h>

//毫秒
#define SLEEP_TIME 1000
#define FILE_PATH "D:\\test.txt"
//服务状态
SERVICE_STATUS m_ServiceState;
//服务状态句柄
SERVICE_STATUS_HANDLE m_ServiceHandle;
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
int WriteToLog(char* str);
BOOL bRunning;

int main() {

	SERVICE_TABLE_ENTRY stentry[2];
	stentry[0].lpServiceName = "demo";
	stentry[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)ServiceMain;
	//服务的最后一项要设置为NULL
	stentry[1].lpServiceName = NULL;
	stentry[1].lpServiceProc = NULL;

	StartServiceCtrlDispatcher(stentry);
	//system("pause");
	return 0;
}

//服务主函数
void WINAPI ServiceMain(int argc, char** argv) {
	MEMORYSTATUS memstatus;
	char str[100];
	int availMem;

	//服务类型和状态
	m_ServiceState.dwServiceType = SERVICE_WIN32;
	m_ServiceState.dwCurrentState = SERVICE_START_PENDING;
	m_ServiceState.dwControlsAccepted = SERVICE_CONTROL_SHUTDOWN | SERVICE_CONTROL_STOP;
	m_ServiceState.dwWin32ExitCode = 0;
	m_ServiceState.dwServiceSpecificExitCode = 0;
	//下面这两个基本不需要,除非服务启动时间很长
	m_ServiceState.dwCheckPoint = 0;
	m_ServiceState.dwWaitHint = 0;

	//注册服务控制函数
	m_ServiceHandle = RegisterServiceCtrlHandler("demo", (LPHANDLER_FUNCTION)ServiceCtrlHandler);
	if (m_ServiceHandle == NULL) {
		WriteToLog("RegisterServiceCtrlHandler failed");
		return;
	}
	WriteToLog("RegisterServiceCtrlHandler success");

	//更新服务状态
	m_ServiceState.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus(m_ServiceHandle, &m_ServiceState);


	memset(str, '\0', 100);
	bRunning = TRUE;
	while (bRunning)
	{
		GlobalMemoryStatus(&memstatus);
		availMem = memstatus.dwAvailVirtual / 1024 / 1024;
		sprintf_s(str, 50 ,"available memory is %d MB, use %d %%", availMem, memstatus.dwMemoryLoad);
		WriteToLog(str);
		Sleep(SLEEP_TIME);

	}
	WriteToLog("service stop!");
}

//服务控制函数(启动,暂停等)
void WINAPI ServiceCtrlHandler(DWORD Opcode) {
	switch (Opcode)
	{
	case SERVICE_CONTROL_STOP:
		bRunning = FALSE;
		m_ServiceState.dwCurrentState = SERVICE_STOPPED;
		break;
	case SERVICE_CONTROL_SHUTDOWN:
		bRunning = FALSE;
		m_ServiceState.dwCurrentState = SERVICE_STOPPED;
		break;
	default:
		break;
	}
	SetServiceStatus(m_ServiceHandle, &m_ServiceState);
}

int WriteToLog(char * str)
{
	FILE* pFile;
	fopen_s(&pFile, FILE_PATH, "a+");
	fprintf_s(pFile, "%s\n", str);
	fclose(pFile);
	return 0;
}

编译并生成后可以用sc命令安装

代码语言:javascript
代码运行次数:0
复制
sc create giantbranchDemo binpath= D:\demo.exe

我们再打开服务即可看到

我们可以直接在上面的图形界面启动,也可以sc启动

启动停止与删除命令

代码语言:javascript
代码运行次数:0
复制
sc start 
sc stop
sc delete

如果程序本身自带启动和删除可以使用下面的:

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
#include <windows.h>

//毫秒
#define SLEEP_TIME 1000
#define FILE_PATH "C:\\test.txt"
#define SERVICENAME "practice"
//服务状态
SERVICE_STATUS m_ServiceState;
//服务状态句柄
SERVICE_STATUS_HANDLE m_ServiceHandle;
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
int WriteToLog(char* str);
BOOL InstallService();
void DelService();
BOOL bRunning;

int main(int argc, char** argv[]) {
	SERVICE_TABLE_ENTRY stentry[2];
	if (argc == 2)
	{
		if (!strcmp(argv[1], "-i"))
		{
			InstallService();
		}else if (!strcmp(argv[1], "-d"))
		{
			DelService();
		}
		return 0;
	}

	stentry[0].lpServiceName = SERVICENAME;
	stentry[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)ServiceMain;
	//服务的最后一项要设置为NULL
	stentry[1].lpServiceName = NULL;
	stentry[1].lpServiceProc = NULL;

	StartServiceCtrlDispatcher(stentry);
	return 0;
}

//服务主函数
void WINAPI ServiceMain(int argc, char** argv) {
	MEMORYSTATUS memstatus;
	char str[100];
	int availMem;

	//服务类型和状态
	m_ServiceState.dwServiceType = SERVICE_WIN32;
	m_ServiceState.dwCurrentState = SERVICE_START_PENDING;
	m_ServiceState.dwControlsAccepted = SERVICE_CONTROL_SHUTDOWN | SERVICE_CONTROL_STOP;
	m_ServiceState.dwWin32ExitCode = 0;
	m_ServiceState.dwServiceSpecificExitCode = 0;
	//下面这两个基本不需要,除非服务启动时间很长
	m_ServiceState.dwCheckPoint = 0;
	m_ServiceState.dwWaitHint = 0;

	//注册服务控制函数
	m_ServiceHandle = RegisterServiceCtrlHandler(SERVICENAME, (LPHANDLER_FUNCTION)ServiceCtrlHandler);
	if (m_ServiceHandle == NULL) {
		WriteToLog("RegisterServiceCtrlHandler failed");
		return;
	}
	WriteToLog("RegisterServiceCtrlHandler success");

	//更新服务状态
	m_ServiceState.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus(m_ServiceHandle, &m_ServiceState);


	memset(str, '\0', 100);
	bRunning = TRUE;
	GlobalMemoryStatus(&memstatus);
	availMem = memstatus.dwAvailVirtual / 1024 / 1024;
	sprintf_s(str, 50, "available memory is %d MB, use %d %%", availMem, memstatus.dwMemoryLoad);
	WriteToLog(str);
	WriteToLog("service is Running!");
}

//服务控制函数(启动,暂停等)
void WINAPI ServiceCtrlHandler(DWORD Opcode) {
	switch (Opcode)
	{
	case SERVICE_CONTROL_STOP:
	case SERVICE_CONTROL_SHUTDOWN:
		bRunning = FALSE;
		m_ServiceState.dwWin32ExitCode = 0;
		m_ServiceState.dwCurrentState = SERVICE_STOPPED;
		break;
	default:
		break;
	}
	SetServiceStatus(m_ServiceHandle, &m_ServiceState);
}

int WriteToLog(char * str)
{
	FILE* pFile;
	fopen_s(&pFile, FILE_PATH, "a+");
	fprintf_s(pFile, "%s\n", str);
	fclose(pFile);
	return 0;
}

BOOL InstallService()
{
	char strDir[1024];
	SC_HANDLE scHandler,schService;
	LPCTSTR lpszBinaryPathName;
	//GetCurrentDirectory(1024, strDir);
	GetModuleFileName(NULL, strDir, 1024);
	printf("%s\n", strDir);
	lpszBinaryPathName = strDir;
	scHandler = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (scHandler == NULL)
	{
		printf("open scmanager failed! May be you don't have the privilage?");
	}
	schService = CreateService(scHandler, SERVICENAME, SERVICENAME,
		SERVICE_ALL_ACCESS,
		SERVICE_WIN32_OWN_PROCESS,
		SERVICE_AUTO_START,
		SERVICE_ERROR_NORMAL,
		lpszBinaryPathName,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL
		);
	if (schService == NULL)
	{
		printf("create service failed~");
		return FALSE;
	}
	CloseServiceHandle(schService);
	CloseServiceHandle(scHandler);
	return TRUE;
}

void DelService()
{
	SC_HANDLE scHandler;
	SC_HANDLE schService;
	SERVICE_STATUS status;
	BOOL isSuccess;
	DWORD errCode;
	
	scHandler = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (scHandler == NULL)
	{
		printf("open scmanager failed! May be you don't have the privilage?");
		return;
	}
	schService = OpenService(scHandler, SERVICENAME, SC_MANAGER_ALL_ACCESS | DELETE);
	if (schService == NULL)
	{
		errCode = GetLastError();
		printf("OpenService failed! code:%d\n", errCode);
		return;
	}
	isSuccess = QueryServiceStatus(schService, &status);
	if (!isSuccess)
	{
		printf("QueryServiceStatus failed!");
		return;
	}
	if (status.dwCurrentState != SERVICE_STOPPED)
	{
		isSuccess = ControlService(schService, SERVICE_CONTROL_STOP, &status);
		if (!isSuccess)
		{
			printf("Stop Service failed!");
			return;
		}
	}
	isSuccess = DeleteService(schService);
	if (!isSuccess)
	{
		printf("DeleteService failed");
		return;
	}
	else {
		printf("DeleteService success");
	}
	CloseServiceHandle(scHandler);
	CloseServiceHandle(schService);

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档