美文网首页
Windows-创建服务

Windows-创建服务

作者: 龙马君 | 来源:发表于2018-04-12 18:47 被阅读35次

    服务创建步骤

    1. 设置服务入口函数ServiceMain,
      StartServiceCtrlDispatcher
    2. 注册服务控制处理器,接收SCM的命令。
      RegisterServiceCtrlHandler
    3. 服务执行,等待停止,反馈状态。

    代码

    #define SERVICE_NAME _T("MyXzmService")
    #define LOGFILE _T("E:\\memstatus.txt")
    
    SERVICE_STATUS ServiceStatus;
    SERVICE_STATUS_HANDLE hStatus;
    
    void WINAPI ServiceMain(int argc, char** argv);
    void ControlHandler(DWORD request);
    int WriteToLog(TCHAR *str);
    int InitService();
    
    // 文章: https://blog.csdn.net/nodeathphoenix/article/details/24181509
    int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPTSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
        OutputDebugString(_T("-------_tWinMain--------"));
    
        SERVICE_TABLE_ENTRY ServiceTable[2];
        ServiceTable[0].lpServiceName = SERVICE_NAME;   // 指向表示服务名称字符串的指针;当定义了多个服务时,那么这个域必须指定; 
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;               // 指向服务主函数的指针(服务入口点); 
    
        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = NULL;
    
        StartServiceCtrlDispatcher(ServiceTable);
        return 0;
    }
    
    // 该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的
    void WINAPI ServiceMain(int argc, char** argv){
        OutputDebugString(_T("ServiceMain start"));
        ServiceStatus.dwServiceType = SERVICE_WIN32;            // 指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32 ; 
        ServiceStatus.dwCurrentState = SERVICE_START_PENDING;   // 指定服务的当前状态
        ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;   // 这个域通知 SCM 服务接受哪个域
        ServiceStatus.dwWin32ExitCode = 0;
        ServiceStatus.dwCheckPoint = 0;
        ServiceStatus.dwWaitHint = 0;
    
        // 为服务注册控制处理器,两个参数传递给此函数:服务名和指向 ControlHandlerfunction 的指针。 
        // 注册完控制处理器之后,获得状态句柄(hStatus)。通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。 
        hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, (LPHANDLER_FUNCTION)ControlHandler);
        if (hStatus == (SERVICE_STATUS_HANDLE)0)
        {
            // Registering Controll Handler failed;
            return;
        }
        OutputDebugString(_T("ServiceMain InitService"));
        int error = InitService();
        if (error)
        {
            OutputDebugString(_T("ServiceMain InitService fail."));
            // 初始化失败,终止服务
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = -1;
            SetServiceStatus(hStatus, &ServiceStatus);
            // 退出ServiceMan
            return;
        }
        ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        SetServiceStatus(hStatus, &ServiceStatus);
    
        //  
        // 不断获取内存大小写入文件
        while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
        {
            TCHAR buffer[100];
            MEMORYSTATUS memory;
            GlobalMemoryStatus(&memory);
            _stprintf_s(buffer, _T("memory.dwAvailPhys=%d"), memory.dwAvailPhys);
            int result = WriteToLog(buffer);
            if (result)
            {
                ServiceStatus.dwCurrentState = SERVICE_STOPPED;
                ServiceStatus.dwWin32ExitCode = -1;
                SetServiceStatus(hStatus, &ServiceStatus);
                return;
            }
    
            // 等待10s
            Sleep(10000);
        }
    }
    
    void ControlHandler(DWORD request){
        switch (request)
        {
        case SERVICE_CONTROL_STOP:
            WriteToLog(_T("Monitoring stoppend."));
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = 0;
            SetServiceStatus(hStatus, &ServiceStatus);
            break;
        case SERVICE_CONTROL_SHUTDOWN:
            WriteToLog(_T("Monitoring shutdown."));
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = 0;
            SetServiceStatus(hStatus, &ServiceStatus);
            break;
        default:
            break;
        }
    }
    
    int InitService(){
        int result;
        result = WriteToLog(_T("Monitoring started."));
        return result;
    }
    
    int WriteToLog(TCHAR *str){
        FILE * log;
        _tfopen_s(&log, LOGFILE, _T("a+"));
        if (log == NULL)
        {
            return -1;
        }
        _ftprintf(log,_T("%s\n"), str);
        fclose(log);
    
        return 0;
    }
    

    SC.exe管理Service

    sc命令的语法格式:

    sc create MyService binpath= e:/xxx/MyService.exe ;创建服务MyService
    sc start MyService ;启动服务
    sc stop MyService ;停止服务
    sc delete MyService ; 删除服务
    sc config 服务名 start= auto|demand|disabled ;修改服务启动类型。start参数的值可以是demand(手动)、disabled(禁用),auto(自动)。
    

    参考

    C++编写Windows服务
    https://blog.csdn.net/nodeathphoenix/article/details/24181509

    相关文章

      网友评论

          本文标题:Windows-创建服务

          本文链接:https://www.haomeiwen.com/subject/qsefkftx.html