代码如下:
#include <windows.h> #include <stdio.h> #include <winsvc.h> #include <string.h> // 服务名称,如果服务为SERVICE_WIN32_OWN_PROCESS 类型,则服务名称被忽略 #define SERVICE_NAME "MyService" // 启动服务入口函数 void WINAPI MyServiceMain(DWORD argc, LPTSTR *argv); // 服务控制函数 void WINAPI MyServiceControl(DWORD nControlCode); // 服务所执行函数 BOOL MyExecuteService(); // 服务终止函数 void MyTerminateService(); // 服务运行后的处理线程 DWORD WINAPI MyServiceProc(LPVOID lpParameter); // 更新服务状态 BOOL MyUpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint); // 服务状态句柄 SERVICE_STATUS_HANDLE hServiceStatus; DWORD ServiceCurrentStatus; HANDLE hServiceThread; BOOL bServiceRunning; HANDLE hServiceEvent; // 信息输出 VOID SvcDebugOut(LPSTR String, DWORD Status) { CHAR Buffer[1024]; if (strlen(String) < 1000) { sprintf(Buffer, String, Status); OutputDebugStringA(Buffer); } } void WINAPI MyServiceMain(DWORD argc, LPTSTR *argv) { // 这里可获得指定的服务启动参数个数,及参数内容 char ddd[128] = {'\0'}; sprintf(ddd, "参数共有%d个", argc); // 注册服务控制回调 hServiceStatus = RegisterServiceCtrlHandler(SERVICE_NAME,(LPHANDLER_FUNCTION)MyServiceControl); if(!hServiceStatus || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000)) { return; } // 创建等待事件 hServiceEvent = CreateEvent(0,TRUE,FALSE,0); if(!hServiceEvent || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000)) { return; } // 运行服务 if( !MyExecuteService() ) { return; } ServiceCurrentStatus = SERVICE_RUNNING; if(!MyUpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0)) { return; } // 等待受信 WaitForSingleObject(hServiceEvent,INFINITE); CloseHandle(hServiceEvent); } // 服务消息处理线程 void WINAPI MyServiceControl(DWORD dwControlCode) { switch(dwControlCode) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: ServiceCurrentStatus = SERVICE_STOP_PENDING; MyUpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000); MyTerminateService(); return; default: break; } MyUpdateServiceStatus(ServiceCurrentStatus,NO_ERROR,0,0,0); } // 执行服务内容线程 BOOL MyExecuteService() { DWORD dwThreadID; // 启动服务线程 hServiceThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) MyServiceProc, 0, 0, &dwThreadID); if (hServiceThread != NULL) { bServiceRunning = TRUE; return TRUE; } else { return FALSE; } } // 停止服务时执行的方法 void MyTerminateService() { // ::MessageBox(NULL, "hello","you kill me ?", MB_ICONWARNING | MB_TOPMOST); bServiceRunning = FALSE; SetEvent(hServiceEvent); MyUpdateServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0); } // 所要进行的操作在此线程中处理 DWORD WINAPI MyServiceProc(LPVOID lpParameter) { while (bServiceRunning) { Beep(450, 150); Sleep(4000); } return 0; } BOOL MyUpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { SERVICE_STATUS ServiceStatus; ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ServiceStatus.dwCurrentState = dwCurrentState; if (dwCurrentState == SERVICE_START_PENDING) { ServiceStatus.dwControlsAccepted = 0; } else { ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; } if (dwServiceSpecificExitCode == 0) { ServiceStatus.dwWin32ExitCode = dwWin32ExitCode; } else { ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; } ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; ServiceStatus.dwCheckPoint = dwCheckPoint; ServiceStatus.dwWaitHint = dwWaitHint; if (!SetServiceStatus(hServiceStatus, &ServiceStatus)) { MyTerminateService(); return FALSE; } return TRUE; } BOOL CreateSampleService() { SC_HANDLE schSCManager; // Open a handle to the SC Manager database. schSCManager = OpenSCManager(NULL, // local machine NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) printf("OpenSCManager failed (%d)\n", GetLastError()); TCHAR szModuleFileName[MAX_PATH]; GetModuleFileName(NULL, szModuleFileName, MAX_PATH); SC_HANDLE schService = CreateService(schSCManager, // SCManager database SERVICE_NAME, // name of service SERVICE_NAME, // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szModuleFileName, // 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()); return FALSE; } else { if (!StartService(schService, NULL, NULL)) { CloseServiceHandle(schService); printf("StartService failed (%d)\n", GetLastError()); return FALSE; } CloseServiceHandle(schService); return TRUE; } } BOOL DeleteSampleService() { SC_HANDLE schSCManager; // Open a handle to the SC Manager database. schSCManager = OpenSCManager(NULL, // local machine NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) printf("OpenSCManager failed (%d)\n", GetLastError()); SC_HANDLE schService = OpenService(schSCManager, // SCManager database SERVICE_NAME, // name of service DELETE); // only need DELETE access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); return FALSE; } if (!DeleteService(schService)) { printf("DeleteService failed (%d)\n", GetLastError()); return FALSE; } else printf("DeleteService succeeded\n"); CloseServiceHandle(schService); return TRUE; } void RunSampleService() { SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, MyServiceMain }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher(ServiceTable)) { SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher (%d)\n", GetLastError()); } } int main(int argc, char* argv[]) { if (argc > 1 && lstrcmpi(argv[1], TEXT("install")) == 0) { CreateSampleService(); } else if (argc > 1 && lstrcmpi(argv[1], TEXT("uninstall")) == 0) { DeleteSampleService(); } else { RunSampleService(); } return 0; }