一个 Windows 服务应用程序






4.66/5 (53投票s)
一个简单的 Windows 服务应用程序,用于派生和监视应用程序。
引言
最近,我遇到一种情况,需要让应用程序在 PC 启动时自动启动。问题是我需要启动的程序被设计成 GUI 应用程序。我想到的使其自动启动的最佳方法是创建一个基于服务的应用程序,以便在用户登录计算机后,应用程序将由服务自动执行并监视该应用程序。然后,我想将多个应用程序附加到一个服务中,并运行它直到该服务被终止或停止。
背景
我搜索了许多站点,寻找一些可以帮助我创建一个简单的 Windows 服务应用程序的代码,该应用程序可以派生和监视一些应用程序,但我只找到了大量关于如何管理系统上当前 Windows 服务的代码。后来,我开始在 MSDN 的帮助下创建我自己的。
描述
这是一个简单的基于 Windows 的服务应用程序,使用 Win32 - VC++ 创建。此应用程序的用途是 - 它将充当一个 Windows 服务,能够派生和监视在此服务下运行的任何数量的子进程。应用程序可以是任何类型,例如 GUI、非 GUI 等。
此应用程序将帮助您了解以下与服务应用程序相关的主题
- 如何创建/安装新的 Windows 服务。
- 如何将某些应用程序映射到特定的 Windows 服务,并通过该服务控制应用程序。(如何连接到控制服务管理器。)
- 如何启动/运行 Windows 服务。
- 如何停止/终止 Windows 服务。
- 如何卸载 Windows 服务。
代码使用
该代码非常简单,并且在很大程度上是不言自明的。应用程序可执行文件被命名为“WinService.exe”。用户必须在执行此应用程序时,通过命令提示符传递一些命令行参数,才能使用其不同的功能。
""ApplicationName FeatureExtension"
注意:默认服务名称将为“Sundar_Service”。用户可以在代码中更改服务名称并重新构建应用程序。
功能扩展
ApplicationName -i / -I - Create / Install New service
ApplicationName - Connect to Service Control Manager
ApplicationName -s / -S - Run / Start the service
ApplicationName -k / -K - Stop / End the service
ApplicationName -u / -U - Uninstall / Kill the service from windows
创建/安装新服务
"WinService -i" or "WinService -I"
当您在命令提示符下键入上述行并按 Enter 键时,您可以在 Windows 服务窗口中看到一个名为“Sundar_Service”的新服务。
VOID Install(char* pPath, char* pName);
Install
方法创建一个服务对象并将其添加到指定的服务控制管理器数据库。
SC_HANDLE schService = CreateService( schSCManager, /* SCManager database */ pName, /* name of service */ pName, /* 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 */ pPath, /* service's binary */ NULL, /* no load ordering group */ NULL, /* no tag identifier */ NULL, /* no dependencies */ NULL, /* LocalSystem account */ NULL ); /* no password */
连接到 SCM(服务控制管理器)
"WinService" or "WinService"
在命令提示符下执行上述命令时,将在服务“Sundar_Service”下映射的子进程将启动。这些进程将由服务监视,以便如果由于任何原因被终止,可以再次启动该应用程序。
VOID ExecuteSubProcess();
“ExecuteSubProcess
”方法使用“_beginthread
”方法定义用于线程创建,这确保了子进程继续执行,直到服务被用户或 Windows 停止。这也将调用“StartServieCtrlDispatcher
”方法。
if(!StartServiceCtrlDispatcher(lpServiceStartTable))
“StartServiceCtrlDispatcher
”将服务进程的主线程连接到服务控制管理器,这导致该线程成为调用进程的服务控制调度器线程。
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
通过 lpServiceStartTable
结构映射的回调功能会将“ServiceHandler
”方法注册到该服务并更新其状态。此外,这将执行其子应用程序。
VOID WINAPI ServiceHandler(DWORD fdwControl)
“ServieHandler
”方法将控制服务功能,例如“启动”、“停止”、“暂停”等。
注意:子应用程序以“1.exe”、“2.exe”、“3.exe”和“4.exe”的形式附加,用户可以在其中更新或更改应用程序。这个示例应用程序将动画化 Windows 系统托盘上的图标。
运行/启动服务
"WinService -s" or "WinService -S"
在命令提示符下执行上述行时,服务“Sundar_Service”将启动。
VOID RunService(char* pPath, char* pName)
用户定义的 RunService
方法将在获取服务控制管理器控制句柄和服务句柄后,使用“StartService
”方法启动服务。
if(StartService(schService, 0, (const char**)NULL))
停止/结束 Windows 服务
"WinService -k" or "WinService -K"
此命令将通过使用“ControlService
”方法将“SERVICE_CONTROL_STOP
”控制代码发送到服务控制管理器来停止服务。这将导致在“ServiceHandler
”方法中执行用户案例功能以停止该服务。
if(ControlService(schService,SERVICE_CONTROL_STOP,&status))
从 Windows 卸载/终止服务
"WinService -u" or "WinService -U"
在所有子进程都已停止后,此命令将从 Windows 服务管理器数据库中卸载该服务。
if(!DeleteService(schService))
“DeleteService
”方法标记要从服务控制管理器数据库中删除的指定服务。
Logger
VOID WriteLog(char* pFile, char* pMsg)
“WriteLog
”方法会将所有错误和服务状态以“Sundar_Service.Log”的形式记录在应用程序路径中,并将服务名称作为日志文件名。