65.9K
CodeProject 正在变化。 阅读更多。
Home

一个 Windows 服务应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (53投票s)

2006年11月22日

CPOL

4分钟阅读

viewsIcon

483644

downloadIcon

17847

一个简单的 Windows 服务应用程序,用于派生和监视应用程序。

引言

最近,我遇到一种情况,需要让应用程序在 PC 启动时自动启动。问题是我需要启动的程序被设计成 GUI 应用程序。我想到的使其自动启动的最佳方法是创建一个基于服务的应用程序,以便在用户登录计算机后,应用程序将由服务自动执行并监视该应用程序。然后,我想将多个应用程序附加到一个服务中,并运行它直到该服务被终止或停止。

背景

我搜索了许多站点,寻找一些可以帮助我创建一个简单的 Windows 服务应用程序的代码,该应用程序可以派生和监视一些应用程序,但我只找到了大量关于如何管理系统上当前 Windows 服务的代码。后来,我开始在 MSDN 的帮助下创建我自己的。

描述

这是一个简单的基于 Windows 的服务应用程序,使用 Win32 - VC++ 创建。此应用程序的用途是 - 它将充当一个 Windows 服务,能够派生和监视在此服务下运行的任何数量的子进程。应用程序可以是任何类型,例如 GUI、非 GUI 等。

此应用程序将帮助您了解以下与服务应用程序相关的主题

  1. 如何创建/安装新的 Windows 服务。
  2. 如何将某些应用程序映射到特定的 Windows 服务,并通过该服务控制应用程序。(如何连接到控制服务管理器。)
  3. 如何启动/运行 Windows 服务。
  4. 如何停止/终止 Windows 服务。
  5. 如何卸载 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"

Sample Image

当您在命令提示符下键入上述行并按 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             */

Sample Image

连接到 SCM(服务控制管理器)

"WinService" or "WinService"

Sample Image

在命令提示符下执行上述命令时,将在服务“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"

Sample Image

在命令提示符下执行上述行时,服务“Sundar_Service”将启动。

VOID RunService(char* pPath, char* pName)

用户定义的 RunService 方法将在获取服务控制管理器控制句柄和服务句柄后,使用“StartService”方法启动服务。

if(StartService(schService, 0, (const char**)NULL))

Sample Image

Sample Image

停止/结束 Windows 服务

"WinService -k" or "WinService -K"

Sample Image

此命令将通过使用“ControlService”方法将“SERVICE_CONTROL_STOP”控制代码发送到服务控制管理器来停止服务。这将导致在“ServiceHandler”方法中执行用户案例功能以停止该服务。

if(ControlService(schService,SERVICE_CONTROL_STOP,&status))

从 Windows 卸载/终止服务

"WinService -u" or "WinService -U"

Sample Image

在所有子进程都已停止后,此命令将从 Windows 服务管理器数据库中卸载该服务。

if(!DeleteService(schService))

DeleteService”方法标记要从服务控制管理器数据库中删除的指定服务。

Sample Image

Logger

Sample Image

VOID WriteLog(char* pFile, char* pMsg)

WriteLog”方法会将所有错误和服务状态以“Sundar_Service.Log”的形式记录在应用程序路径中,并将服务名称作为日志文件名。

© . All rights reserved.