C++之创建Windows系统服务

Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这种服务非常适合在服务器上使用,或任何时候,为了不影响在同一台计算机上工作的其他用户,需要长时间运行功能时使用。

一.一个简单的Windows服务

#include 
#include 
#include 
#include 

#pragma comment (lib,"Advapi32.lib")

#define SERVICE_NAME "TestService"
#define SERVICE_DESC "TestService cao shang pa"

SERVICE_STATUS gServiceStatus;
SERVICE_STATUS_HANDLE gServiceStatusHandle;
HANDLE gServiceStopEvent = NULL;

void WINAPI ServiceMain(int argc, char** argv);
void WINAPI ServiceCtrlHandler(DWORD request);
void ReportServiceStatus(DWORD CurrentStatus, DWORD Win32ExitCode, DWORD WaitHint);

void WINAPI ServiceMain(int argc, char** argv)
{
    gServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

    if (!gServiceStatusHandle)
    {
        std::cout<<"RegisterServiceCtrlHandler failed"<(std::string(SERVICE_NAME).c_str());
    entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    entrytable[1].lpServiceName = NULL;
    entrytable[1].lpServiceProc = NULL;
    // 也可以写成下面这种形式.
    //    SERVICE_TABLE_ENTRY entrytable[] =
    //    {
    //        {
    //            SERVICE_NAME,
    //            (LPSERVICE_MAIN_FUNCTION)ServiceMain
    //        },
    //        {
    //            NULL,
    //            NULL
    //        }
    //    };

    if (!StartServiceCtrlDispatcher(entrytable))
    {
        std::cout<<"StartServiceCtrlDispatcher failed";
        OutputDebugString("StartServiceCtrlDispatcher failed");
    }

    return 0;
}

代码很简单,api手册上都可以查到,需要注意的一点是ServiceMain函数是服务的入口点,它运行在一个单独的线程当中,这个线程是由控制分派器创建的。

下面是一些服务相关的操作

// 创建服务,注意"="后面有一个空格
sc create TestService binpath= C:\Users\zhang\Desktop\TestService\out\TestService.exe
// 启动服务器
sc start TestService 
// 查询服务当前状态
sc query TestService 
// 停止服务
sc stop TestService 
// 删除服务
sc delete TestService

下面是安装服务的脚本InstallService.bat

@echo off

rem 获取绝对路径
set "CURRENT_DIR=%~dp0"

set "EXE_NAME=TestService.exe"

@echo %CURRENT_DIR%%EXE_NAME%

rem 创建windows服务
sc create TestService binpath= %CURRENT_DIR%%EXE_NAME%
sc config TestService start=AUTO
sc start TestService

下面是卸载服务的脚本UninstallService.bat

@echo off

rem 获取绝对路径
set "CURRENT_DIR=%~dp0"

set "EXE_NAME=TestService.exe"

@echo %CURRENT_DIR%%EXE_NAME%

rem 删除windows服务
sc stop TestService
sc delete TestService

当然也可以在代码中完成InstallService.bat和UninstallService.bat这两个脚本的功能

int InstallService()
{
    if (IsInstalled())
    {
        std::cout<<"Service already installed"<
int UninstallService()
{
    if (!IsInstalled())
    {
        std::cout<<"Service not installed"<

然后把main函数也改一下

int main(int argc, char *argv[])
{
    if (argc == 2)
    {
        if (strcmp(argv[1], "-install") == 0)
        {
            InstallService();
        }
        else if (strcmp(argv[1], "-uninstall") == 0)
        {
            UninstallService();
        }
    }
    else
    {
        SERVICE_TABLE_ENTRY entrytable[2];
        entrytable[0].lpServiceName = const_cast(std::string(SERVICE_NAME).c_str());
        entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
        entrytable[1].lpServiceName = NULL;
        entrytable[1].lpServiceProc = NULL;
        // 也可以写成下面这种形式.
        //    SERVICE_TABLE_ENTRY entrytable[] =
        //    {
        //        {
        //            SERVICE_NAME,
        //            (LPSERVICE_MAIN_FUNCTION)ServiceMain
        //        },
        //        {
        //            NULL,
        //            NULL
        //        }
        //    };

        if (!StartServiceCtrlDispatcher(entrytable))
        {
            std::cout<<"StartServiceCtrlDispatcher failed";
            OutputDebugString("StartServiceCtrlDispatcher failed");
        }
    }

    return 0;
}

这样就能用下面的指令来安装和卸载服务了

TestService -install
TestService -uninstall

二.DebugView调试工具

我们可以用这款软件来调试windows服务程序,代码中用OutputDebugString打印调试信息,DebugView就能捕获并显示出来
如下图所示,把能勾的都勾上
C++之创建Windows系统服务_第1张图片

原文链接:https://blog.csdn.net/caoshangpa/article/details/79475677

你可能感兴趣的:(C/C++,Windows服务,C++,SCM)