工控安全系统编程之编写和安装服务程序

主要就是编写服务程序,然后用工具把服务程序安装到电脑的服务里,真正的作为电脑的服务跑起来
这是安装服务程序的工具
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
在这里插入图片描述
这是服务程序的代码

#include "windows.h"
#include "process.h"
#include "strsafe.h"

#define LOG_FILE_PATH	TEXT("D:\\ServiceTest.txt")

VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);
VOID WINAPI ServiceHandler(DWORD fdwControl);
UINT WINAPI ThreadTest(PVOID pData);
VOID RenewFile();
VOID OutPutErrorMessage(DWORD dwMessageID);

BOOL					g_blContinue;
DWORD					g_dwCurrentState;
SERVICE_STATUS			g_ServiceStatus;
SERVICE_STATUS_HANDLE	g_ServiceStatusHandle;

int main()
{
	SERVICE_TABLE_ENTRY	ServiceTable[] = {TEXT("ServiceTest"), ServiceMain, NULL, NULL};

	//连接scm
	StartServiceCtrlDispatcher(ServiceTable);

	return	0;
}

/************************************************************************/
/* 
 功能:更改服务状态
 参数:dwCurrentState				- 设置的当前的服务的状态
	   dwWin32ExitCode				- 错误代码
	   dwServiceSpecificExitCode	- 特定的错误代码
	   dwWaitHint					- 预计操作完成的时间
 返回:
 原理:
 注意:

 创建时间:2012-1-16   12:07
*/
/************************************************************************/
void ReportServiceStatus(DWORD dwCurrentState, 
						 DWORD dwWin32ExitCode, 
						 DWORD dwServiceSpecificExitCode, 
						 DWORD dwWaitHint
						 )
{
	static DWORD dwCheckPoint = 1;

	g_ServiceStatus.dwCurrentState = g_dwCurrentState = dwCurrentState;
	g_ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
	g_ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
	g_ServiceStatus.dwWaitHint = dwWaitHint;

	if (SERVICE_START_PENDING == dwCurrentState)
	{
		g_ServiceStatus.dwControlsAccepted = 0;
	}
	else
	{
		g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	}

	if (SERVICE_RUNNING == dwCurrentState || SERVICE_STOPPED == dwCurrentState)
	{
		g_ServiceStatus.dwCheckPoint = 0;
	}
	else
	{
		g_ServiceStatus.dwCheckPoint = dwCheckPoint ++;
	}

	SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
}


VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
	g_ServiceStatusHandle = RegisterServiceCtrlHandler(TEXT("ServiceTest"), ServiceHandler);
	if (NULL == g_ServiceStatusHandle)
	{
		return	;
	}

	//服务状态
	DWORD	dwError = 0;

	g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP || SERVICE_ACCEPT_SHUTDOWN;
	g_ServiceStatus.dwWin32ExitCode = 0;
	g_ServiceStatus.dwServiceSpecificExitCode = 0;
	g_ServiceStatus.dwWaitHint = 0;

	ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1000);
	
	//初始工作
	HANDLE	hWorkThread;

	hWorkThread = (HANDLE)_beginthreadex(NULL, 0,
		ThreadTest, NULL, 
		0, NULL
		);
	if (NULL == hWorkThread)
	{
		dwError = GetLastError();
	}
	else
	{
		CloseHandle(hWorkThread);
	}
	
	if (ERROR_SUCCESS != dwError)
	{
		ReportServiceStatus(SERVICE_ERROR_NORMAL, ERROR_SERVICE_SPECIFIC_ERROR, dwError, 0);
	}
	else
	{
		ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
	}
}

VOID WINAPI ServiceHandler(DWORD fdwControl)
{
	switch (fdwControl)
	{
	case SERVICE_CONTROL_SHUTDOWN:
	case SERVICE_CONTROL_STOP:
		{
			g_blContinue = FALSE;
			ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 2000);
			//让工作线程来设置服务的停止状态
			break;
		}
	case SERVICE_CONTROL_CONTINUE:
		{
			ReportServiceStatus(SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1000);
			ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
			break;
		}
	case SERVICE_CONTROL_PAUSE:
		{
			ReportServiceStatus(SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1000);
			ReportServiceStatus(SERVICE_PAUSED, NO_ERROR, 0, 0);
			break;
		}
	case SERVICE_CONTROL_INTERROGATE:
		{
			ReportServiceStatus(g_dwCurrentState, 0, 0, 0);
			break;
		}
	default:
		break;
	}
}

//测试工作线程
UINT WINAPI ThreadTest(PVOID pData)
{
	CHAR	szBuffer[128] = {0};
	DWORD	dwBytesWritten = 0;

	g_blContinue = TRUE;
	while (TRUE == g_blContinue)
	{
		Sleep(1000);
		RenewFile();
	}
	ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);

	return	0;
}

//更新文件
VOID RenewFile()
{
	CHAR			szBuffer[128] = {'\0'};
	DWORD			dwBytesWritten = 0;
	SYSTEMTIME		SystemTime = {0};
	HANDLE			hFile = NULL;
	
	hFile = CreateFile(LOG_FILE_PATH,
		FILE_APPEND_DATA,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
		);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		OutPutErrorMessage(GetLastError());
		return	;
	}

	GetLocalTime(&SystemTime);

	StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), TEXT("%02s-%02u-%02u\r\n",), "3170706006",
		SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);

	WriteFile(hFile, szBuffer, lstrlen(szBuffer), &dwBytesWritten, NULL);

	CloseHandle(hFile);
}

VOID OutPutErrorMessage(DWORD dwMessageID)
{
	TCHAR	*pErrorMessage;

	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		dwMessageID,
		0,
		(LPTSTR)&pErrorMessage,
		0,
		NULL
		);
	MessageBox(NULL, pErrorMessage, TEXT("ERROR"), MB_OK|MB_ICONHAND);
	LocalFree( pErrorMessage );  
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果不用现成的工具安装服务程序 也可以手写安装服务程序的程序 如下

#include "windows.h"
#include "process.h"
#include "strsafe.h"

//导出函数
extern "C" __declspec(dllexport) VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);

#define LOG_FILE_PATH	TEXT("D:\\DllService.txt")

VOID WINAPI ServiceHandler(DWORD fdwControl);
UINT WINAPI ThreadTest(PVOID pData);
VOID RenewFile();

BOOL					g_blContinue;
DWORD					g_dwCurrentState;
HANDLE					g_hWaitEvent;
SERVICE_STATUS			g_ServiceStatus;
SERVICE_STATUS_HANDLE	g_ServiceStatusHandle;

BOOL APIENTRY DllMain( HANDLE _HDllHandle,  DWORD _Reason,  LPVOID _Reserved)
{
	switch (_Reason)
	{
		case DLL_PROCESS_ATTACH:
			break;
		case  DLL_PROCESS_DETACH:
			break;
		default:
			break;
	}
	return	TRUE;
}

/* 
 功能:更改服务状态
 参数:dwCurrentState				- 设置的当前的服务的状态
	   dwWin32ExitCode				- 错误代码
	   dwServiceSpecificExitCode	- 特定的错误代码
	   dwWaitHint					- 预计操作完成的时间(对于有pending的状态才有效)
 返回:错误代码
 原理:
 注意:

 创建时间:2012-1-16   12:07
*/
/************************************************************************/
void ReportServiceStatus(DWORD dwCurrentState, 
						 DWORD dwWin32ExitCode, 
						 DWORD dwServiceSpecificExitCode, 
						 DWORD dwWaitHint
						 )
{
	static DWORD dwCheckPoint = 1;

	g_ServiceStatus.dwCurrentState = g_dwCurrentState = dwCurrentState;
	g_ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
	g_ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
	g_ServiceStatus.dwWaitHint = dwWaitHint;

	if (SERVICE_START_PENDING == dwCurrentState || 
		SERVICE_STOP_PENDING == dwCurrentState)
	{
		g_ServiceStatus.dwControlsAccepted = 0;
	}
	else
	{
		g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	}

	if (SERVICE_RUNNING == dwCurrentState || 
		SERVICE_STOPPED == dwCurrentState)
	{
		g_ServiceStatus.dwCheckPoint = 0;
	}
	else
	{
		g_ServiceStatus.dwCheckPoint = dwCheckPoint ++;
	}

	::SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
}

/************************************************************************/
/* 
功能:服务入口点
参数:参数参见MSDN吧
原理:
*/
/************************************************************************/
VOID WINAPI ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv)
{
	WCHAR	szServiceName[256] = {L'\0'};

	::StringCchCopyW(szServiceName, ARRAYSIZE(szServiceName), lpszArgv[0]);
	g_ServiceStatusHandle = ::RegisterServiceCtrlHandlerW(szServiceName, ::ServiceHandler);
	if (NULL == g_ServiceStatusHandle)
	{
		::ReportServiceStatus(SERVICE_ERROR_CRITICAL, 
			ERROR_SERVICE_SPECIFIC_ERROR, 
			::GetLastError(), 
			0
			);
		return	;
	}
	
	//服务状态
	g_ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
	g_ServiceStatus.dwControlsAccepted = (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
	g_ServiceStatus.dwCheckPoint = 0;
	g_ServiceStatus.dwWin32ExitCode = 0;
	g_ServiceStatus.dwServiceSpecificExitCode = 0;
	g_ServiceStatus.dwWaitHint = 0;

	ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1000);

	//初始操作
	HANDLE	hWorkThread;

	g_blContinue = TRUE;
	hWorkThread = (HANDLE)::_beginthreadex(NULL, 0,
		::ThreadTest, NULL,
		0, NULL
		);
	::CloseHandle(hWorkThread);

	ReportServiceStatus(SERVICE_START, NO_ERROR, 0, 0);
	ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);

	g_hWaitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
	
	::WaitForSingleObject(g_hWaitEvent, INFINITE);
	::CloseHandle(g_hWaitEvent);

	ReportServiceStatus(SERVICE_STOPPED, 0, 0, 0);
}

/************************************************************************/
/* 
功能:服务命令处理
参数:fdwControl-contrl code控制码(感觉翻译好难听哦~_~)
原理:
*/
/************************************************************************/
VOID WINAPI ServiceHandler(DWORD fdwControl)
{
	//只是示意,注册函数时,并声明未接收这些命令
	switch (fdwControl)
	{
	case SERVICE_CONTROL_SHUTDOWN:
	case SERVICE_CONTROL_STOP:
		{
			g_blContinue = FALSE;
			ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1000);
			//让工作线程来设置服务的停止状态
			break;
		}
	case SERVICE_CONTROL_CONTINUE:
		{
			ReportServiceStatus(SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1000);
			ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
			break;
		}
	case SERVICE_CONTROL_PAUSE:
		{
			ReportServiceStatus(SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1000);
			ReportServiceStatus(SERVICE_PAUSED, NO_ERROR, 0, 0);
			break;
		}
	case SERVICE_CONTROL_INTERROGATE:
		{
			ReportServiceStatus(g_dwCurrentState, 0, 0, 0);
			break;
		}
	default:
		break;
	}
}

//测试工作线程
UINT WINAPI ThreadTest(PVOID pData)
{
	CHAR	szBuffer[128] = {0};
	DWORD	dwBytesWritten = 0;

	g_blContinue = TRUE;
	while (TRUE == g_blContinue)
	{
		::Sleep(1000);
		RenewFile();
	}
	::SetEvent(g_hWaitEvent);

	return	0;
}

//更新文件
VOID RenewFile()
{
	CHAR			szBuffer[128] = {'\0'};
	DWORD			dwBytesWritten = 0;
	SYSTEMTIME		SystemTime = {0};
	HANDLE			hFile = NULL;

	hFile = CreateFile(LOG_FILE_PATH,
		FILE_APPEND_DATA,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
		);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return	;
	}

	GetLocalTime(&SystemTime);

	StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), TEXT("%s-%u-%u\r\n"),"3170706006", 
		SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);

	WriteFile(hFile, szBuffer, lstrlen(szBuffer), &dwBytesWritten, NULL);

	CloseHandle(hFile);
}

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页