windows服务程序初探

// serviceProgram.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> //服务程序:当一个应用程序需要常驻系统,或者随时为其它应用程序提供服务时,可以使用服务应用程序 SERVICE_STATUS g_SplSrvServieStatus; SERVICE_STATUS_HANDLE g_SplSrvServiceStatusHandle; /* 显示信息给调试器 */ VOID SrvDebugOut(LPCTSTR str, DWORD dwStatus); /* 服务入口函数 */ VOID WINAPI SplSrvServiceStart(DWORD dwArgv, LPTSTR* lpszArgv); /* 控制请求处理函数 */ VOID WINAPI SplSrvServiceCtrlHander(DWORD dwControlCode); /* 初始化工作(用户自定义内容)*/ DWORD SplSrvServiceInitialization(DWORD dwArgc, LPTSTR* lpszArgv, DWORD* pdwErrorCode); VOID SrvDebugOut(LPCTSTR str, DWORD dwStatus) { TCHAR szBuffer[1024] = { 0 }; _sntprintf(szBuffer, 1024, str, dwStatus); OutputDebugString(szBuffer); } VOID WINAPI SplSrvServiceCtrlHander(DWORD dwControlCode) { DWORD dwStatus; switch(dwControlCode) { case SERVICE_CONTROL_PAUSE: g_SplSrvServieStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: g_SplSrvServieStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: g_SplSrvServieStatus.dwWin32ExitCode = 0; g_SplSrvServieStatus.dwCurrentState = SERVICE_STOPPED; g_SplSrvServieStatus.dwCheckPoint = 0; g_SplSrvServieStatus.dwWaitHint = 0; if (!SetServiceStatus(g_SplSrvServiceStatusHandle, &g_SplSrvServieStatus)) { dwStatus = ::GetLastError(); SrvDebugOut(_T("[SPL_SERVICE] SetServiceStatus Error %ld/n"), dwStatus); } SrvDebugOut(_T("[SPL_SERVICE] Leaving SplSrvService /n"), 0); return; case SERVICE_CONTROL_INTERROGATE: ::MessageBeep(MB_OK); break; default: SrvDebugOut(_T("[SPL_SERVICE] Unrecognized dwControlCode %ld/n"), dwControlCode); } if (!SetServiceStatus(g_SplSrvServiceStatusHandle, &g_SplSrvServieStatus)) { dwStatus = ::GetLastError(); SrvDebugOut(_T("[SPL_SERVICE] SetServiceStatus %ld/n"), dwStatus); } return; } VOID WINAPI SplSrvServiceStart(DWORD dwArgc, LPTSTR* lpszArgv) { DWORD dwStatus; DWORD dwSpecificError; g_SplSrvServieStatus.dwServiceType = SERVICE_WIN32; g_SplSrvServieStatus.dwCurrentState = SERVICE_START_PENDING; g_SplSrvServieStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; g_SplSrvServieStatus.dwWin32ExitCode = 0; g_SplSrvServieStatus.dwServiceSpecificExitCode = 0; g_SplSrvServieStatus.dwCheckPoint = 0; g_SplSrvServieStatus.dwWaitHint = 0; /* 注册服务控制请求 */ g_SplSrvServiceStatusHandle = ::RegisterServiceCtrlHandler(_T("063"), SplSrvServiceCtrlHander); if (g_SplSrvServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { SrvDebugOut(_T("[SPL_SERVICE] RegisterServiceCtrlHandler Failed %d/n"), ::GetLastError()); return; } dwStatus = SplSrvServiceInitialization(dwArgc, lpszArgv, &dwSpecificError); if (dwStatus != NO_ERROR) { g_SplSrvServieStatus.dwCurrentState = SERVICE_STOPPED; g_SplSrvServieStatus.dwCheckPoint = 0; g_SplSrvServieStatus.dwWaitHint = 0; g_SplSrvServieStatus.dwWin32ExitCode = dwStatus; g_SplSrvServieStatus.dwServiceSpecificExitCode = dwSpecificError; ::SetServiceStatus(g_SplSrvServiceStatusHandle, &g_SplSrvServieStatus); return; } g_SplSrvServieStatus.dwCurrentState = SERVICE_RUNNING; g_SplSrvServieStatus.dwCheckPoint = 0; g_SplSrvServieStatus.dwWaitHint = 0; if (!SetServiceStatus(g_SplSrvServiceStatusHandle, &g_SplSrvServieStatus)) { dwStatus = ::GetLastError(); SrvDebugOut(_T("[SPLSRV_SERVICE] SetServiceStatus Error %ld/n"), dwStatus); } /* 用户自定义工作任务 */ SrvDebugOut(_T("[SPLSRV_SERVICE] Returning the Main Thread /n"), 0); return; } DWORD SplSrvServiceInitialization(DWORD dwArgc, LPTSTR* lpszArgv, DWORD* pdwErrorCode) { return 0; } int _tmain(int argc, _TCHAR* argv[]) { SERVICE_TABLE_ENTRY DispatchTable[] = { {_T("063"), (LPSERVICE_MAIN_FUNCTION)SplSrvServiceStart}, {NULL, NULL}, }; if (!::StartServiceCtrlDispatcher(DispatchTable)) { SrvDebugOut(_T("[SPLSRV_SERVICE] StartServiceCtrlDispatcher %d/n"), ::GetLastError()); } return 0; } /* 服务程序执行流程描述(实验得到) */ /* 1.sc.exe create SerName binpath= f://serviceProgram.exe 创建服务,然后在windows服务管理器中就可以看到你创建的服务 2.启动服务-> 执行入口函数_tmain 进入启动函数SplSrvServiceStart 3.暂停服务-> 执行控制请求处理函数并带参数SERVICE_CONTROL_PAUSE 4.恢复服务-> 执行控制请求处理函数并带参数SERVICE_CONTROL_PAUSE 5.停止服务-> 执行控制请求处理函数并带参数SERVICE_CONTROL_STOP 如果启动函数SplSrvServiceStart中未返回就返回(其中如果没有循环或者创建线程等等就早已经返回的了,不存在此时返回) 返回到_tmain,执行StartServiceCtrlDispatcher后面的代码 6.删除服务 sc.exe delete SerName 上面结论通过MessageBox验证得到,其实还有很多疑惑的地方(比如启动服务后,从SplSrvServiceStart返回后,这个线程干了什么?为什么没有返回到_tmain,究竟是怎么实现暂停的然后又恢复的?服务程序的模型是怎么样子?) */

你可能感兴趣的:(thread,windows,service,null,returning,winapi)