window服务调试(一):winodw服务运行原理

window服务调试(一):winodw服务运行原理

windows服务运行主要由三部分构成:安装windows服务 启动windows服务 卸载windows服务

一、安装window服务

安装window服务的原理是获取到SCM(服务控制管理器)的句柄,然后将服务名和该服务的可执行路径写入SCM中以注册一个服务,用到的Windows API有 OpenSCManager、CreateService

示例代码:

VOID SvcInstall()
{
	SC_HANDLE schSCManager;
	SC_HANDLE schService;
	TCHAR szPath[MAX_PATH];

	if (!GetModuleFileName(NULL, szPath, MAX_PATH))
	{
		printf("Cannot install service (%d)\n", GetLastError());
		return;
	}

	// Get a handle to the SCM database. 

	schSCManager = OpenSCManager(
		NULL,                    // local computer
		NULL,                    // ServicesActive database 
		SC_MANAGER_ALL_ACCESS);  // full access rights 

	if (NULL == schSCManager)
	{
		printf("OpenSCManager failed (%d)\n", GetLastError());
		return;
	}

	// Create the service

	schService = CreateService(
		schSCManager,              // SCM database 
		SVCNAME,                   // name of service 
		SVCNAME,                   // service name to display 
		SERVICE_ALL_ACCESS,        // desired access 
		SERVICE_WIN32_OWN_PROCESS, // service type 
		SERVICE_DEMAND_START,      // start type 
		SERVICE_ERROR_NORMAL,      // error control type 
		szPath,                    // path to service‘s binary 
		NULL,                      // no load ordering group 
		NULL,                      // no tag identifier 
		NULL,                      // no dependencies 
		NULL,                      // LocalSystem account 
		NULL);                     // no password 

	if (schService == NULL)
	{
		printf("CreateService failed (%d)\n", GetLastError());
		CloseServiceHandle(schSCManager);
		return;
	}
	else printf("Service installed successfully\n");

	CloseServiceHandle(schService);
	CloseServiceHandle(schSCManager);
}

启动window服务

winodw服务并不是服务程序启动的,而是由SCM启动的,如下图所示( 按win+R 输入services.msc即可打开服务)当你启动这个服务时,SCM就会按照之前安装服务给出的路径去启动服务程序

window服务调试(一):winodw服务运行原理

这个时候

1.你需要告诉SCM主要的服务函数在哪里,然后SCM就会调用这个函(StartServiceCtrlDispatcher)
2.用一个回调函数处理当SCM停止服务、暂停服务、恢复服务要做哪些操作(RegisterServiceCtrlHandler)
3.最后在主要的服务函数中告诉SCM启动成功(setSvcStatus或ReportSvcStatus)
示例代码

{
	// If command-line parameter is "install", install the service. 
	// Otherwise, the service is probably being started by the SCM.

	if (lstrcmpi(argv[1], TEXT("install")) == 0)
	{
		SvcInstall();
		return;
	}

	// TO_DO: Add any additional services for the process to this table.
	SERVICE_TABLE_ENTRY DispatchTable[] =
	{
		{ SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
		{ NULL, NULL }
	};

	DWORD dw_RetCode = -1;

	// This call returns when the service has stopped. 
	// The process should simply terminate when the call returns.

	if (!StartServiceCtrlDispatcher(DispatchTable))
	{
		dw_RetCode = GetLastError();
		MessageBoxEx(NULL, _T("start SvrName service fail!"), NULL, 0, 0);
		SvcReportEvent(TEXT("StartServiceCtrlDispatcher"));
	}
}
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
	// Register the handler function for the service

	gSvcStatusHandle = RegisterServiceCtrlHandler(
		SVCNAME,
		SvcCtrlHandler);

	if (!gSvcStatusHandle)
	{
		SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
		return;
	}

	// These SERVICE_STATUS members remain as set here

	gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	gSvcStatus.dwServiceSpecificExitCode = 0;
	gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE;


	WriteToLog("in SvrMain(), start Service success!");

	// Report initial status to the SCM

	ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);

	// Perform service-specific initialization and work.

	SvcInit(dwArgc, lpszArgv);
}```
#### 卸载window服务
##### 卸载Window服务是最简单的,利用OpenSCManager和OpenService获取服务句柄,再用DeleteService删除服务即可

window服务调试(一):winodw服务运行原理

上一篇:你应该知道的CSS文字大小单位PX、EM、PT[转]


下一篇:PHP判断用户所在国家并跳转对应的目录