代码如下:
#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;
}