• windows nt service 框架


    // Service.cpp : Defines the entry point for the console application.
    //

    //服务程序主函数。

    #include "stdafx.h"

    #include "Windows.h"

    #define SZAPPNAME      "serverSample"     //服务程序名

    #define SZSERVICENAME  "serviceSample"    //标识服务的内部名



    //内部变量

    bool                   bDebugServer=false;

    SERVICE_STATUS              ssStatus;

    SERVICE_STATUS_HANDLE  sshStatusHandle;

    DWORD                       dwErr=0;

    TCHAR                       szErr[256];



    //下面的函数由程序实现

    void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);

    void  WINAPI  Service_Ctrl(DWORD dwCtrlCode);

    void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);//具体服务的初始化入口函数

    void installService();

    void removeService();

    void debugService(int argc,char** argv);

    bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);

    void AddToMessageLog(LPTSTR lpszMsg);



    //int _tmain(int argc, _TCHAR* argv[])
    int _tmain(int argc, TCHAR* argv[])

    {   

        SERVICE_TABLE_ENTRY dispatchTable[]=
        {

            {TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},

            { NULL,NULL}

        };

        if((argc>1)&&((*argv[1]=='-')||(argv[1]==TEXT("/"))))

        {

            if(_tcsicmp(TEXT("install"),argv[1]+1)==0)

            {

                installService();

            }

            else if(_tcsicmp(TEXT("remove"),argv[1]+1)==0)

            {

                removeService();

            }

            else if(_tcsicmp(TEXT("debug"),argv[1]+1)==0)

            {

                bDebugServer=true;

                //debugService(argc,argv);

            }

            else

            {        //如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用

                //StartServiceCtrlDispatcher 函数。

                printf("%s - install to install the service \n",SZAPPNAME);

                printf("%s - remove to remove the service \n",SZAPPNAME);

                printf("%s - debug to debug the service \n",SZAPPNAME);

                printf("\n StartServiceCtrlDispatcher being called.\n");

                printf("This may take several seconds.Please wait.\n");

                if(!StartServiceCtrlDispatcher(dispatchTable))

                    AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));

                else

                    AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));

            }

            exit(0);

        }

        return 0;

    }

    //服务入口点函数

    void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv)    //具体服务的初始化入口函数
    {
     printf("\n StartServiceCtrlDispatcher being called.\n");

    }

    void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)

    {

        //注册服务控制处理函数

        sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);

        //如果注册失败

        if(!sshStatusHandle)

        {

            goto cleanup;

            return;

        }

        //初始化 SERVICE_STATUS 结构中的成员

        ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;

        ssStatus.dwServiceSpecificExitCode=0;

        //更新服务状态

        if(!ReportStatusToSCMgr(

            SERVICE_START_PENDING,//服务状态,The service is starting.

            NO_ERROR,            //退出码        

            3000))                   //等待时间

            goto cleanup;        //更新服务状态失败则转向 cleanup

        ServiceStart(dwArgc,lpszArgv);

        return;

    cleanup:

        //把服务状态更新为 SERVICE_STOPPED,并退出。

        if(sshStatusHandle)

            (void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);

    }

    //控制处理程序函数

    void WINAPI Service_Ctrl(DWORD dwCtrlCode)

    {

        //处理控制请求码

        switch(dwCtrlCode)

        {

            // 先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。

        case SERVICE_CONTROL_STOP:

            ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

            //ServiceStop();     //由具体的服务程序实现

            return;

            // 暂停服务

        case SERVICE_CONTROL_PAUSE:

            ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

            //ServicePause();    //由具体的服务程序实现

            ssStatus.dwCurrentState=SERVICE_PAUSED;

            return;

            // 继续服务

        case SERVICE_CONTROL_CONTINUE:

            ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

            //ServiceContinue(); //由具体的服务程序实现

            ssStatus.dwCurrentState=SERVICE_RUNNING;

            return;

            // 更新服务状态

        case SERVICE_CONTROL_INTERROGATE:

            break;

            // 无效控制码

        default:

            break;

        }

        ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);

    }

    //安装服务程序

    void installService()

    {

        SC_HANDLE schService;

        SC_HANDLE schSCManager;

        TCHAR szPath[512];

        //得到程序磁盘文件的路径

        if(GetModuleFileName(NULL,szPath,512)==0)

        {

            _tprintf(TEXT("Unable to install %s - %s \n"),

                TEXT(SZAPPNAME),

                GetLastError());//@1获取调用函数返回的最后错误码

            return;

        }

        //打开服务管理数据库

        schSCManager=OpenSCManager(

            NULL,    //本地计算机

            NULL,    //默认的数据库

            SC_MANAGER_ALL_ACCESS  //要求所有的访问权

            );

        if(schSCManager)

        {

            // 登记服务程序

            schService = CreateService(

                schSCManager,                    //服务管理数据库句柄

                TEXT(SZSERVICENAME),             //服务名

                TEXT(SZAPPNAME),       //用于显示服务的标识

                SERVICE_ALL_ACCESS,              //响应所有的访问请求

                SERVICE_WIN32_OWN_PROCESS,       //服务类型

                //SERVICE_DEMAND_START,            //启动类型
                SERVICE_AUTO_START,

                SERVICE_ERROR_NORMAL,            //错误控制类型

                szPath,                              //服务程序磁盘文件的路径

                NULL,                                //服务不属于任何组

                NULL,                                //没有tag标识符

                NULL,              //启动服务所依赖的服务或服务组,这里仅仅是一个空字符串

                NULL,                                //LocalSystem 帐号

                NULL);

            if(schService)

            {

                _tprintf(TEXT("%s installed. \n"),TEXT(SZAPPNAME));

                CloseServiceHandle(schService);

            }

            else

            {

                _tprintf(TEXT("CreateService failed - %s \n"),GetLastError());

            }

            CloseServiceHandle(schSCManager);

        }

        else

            _tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());

    }

    void removeService()
    {
        SC_HANDLE service, scm;             //定义服务句柄和服务控制管理数据库句柄
        SERVICE_STATUS status;                //定义服务状态结构
        //if (argc != 2)  return;             //如果命令行参数的个数小于2,则不执行卸载程序
        // 打开服务控制管理数据库,并返回服务控制管理数据库的句柄
        scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
        // 获得服务句柄,并添加服务访问中的删除选项
        //service = OpenService(scm, argv[1],SERVICE_ALL_ACCESS | DELETE);
        service = OpenService(scm, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS | DELETE);
        // 获得服务的当前状态
        QueryServiceStatus(service, &status);
        // 如果服务不处于停止状态,则将其状态设置为停止状态
        if (status.dwCurrentState != SERVICE_STOPPED)
            ControlService(service,SERVICE_CONTROL_STOP, &status);
        DeleteService(service);                // 删除服务
        CloseServiceHandle(service);        // 关闭新服务句柄
        CloseServiceHandle(scm);            // 关闭服务控制管理数据库句柄

    }


    void debugService(int argc,char** argv)
    {


    }

    bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
    {
       return true;
    }

    void AddToMessageLog(LPTSTR lpszMsg)
    {
     

    }

    http://blog.chinaunix.net/u1/37538/showart_493320.html

    http://www.wei2008.com/Code/softdown.asp?softid=35719 

  • 相关阅读:
    kafka报错:Invalid message size: 0
    转载:elastic5.x部署常见问题总结
    hadoop集群zookeeper迁移
    生产环境轻量级dns服务器dnsmasq搭建文档
    (3)安装elastic6.1.3及插件kibana,x-pack,essql,head,bigdesk,cerebro,ik
    (2)安装elastic6.1.3及插件kibana,x-pack,essql,head,bigdesk,cerebro,ik
    (1)安装elastic6.1.3及插件kibana,x-pack,essql,head,bigdesk,cerebro,ik
    换种思路解决日志占用磁盘空间问题
    更改hadoop集群yarn的webui中的开始时间和结束时间为本地时间
    两种虚拟机扩容方式扩容后在线生效的方法
  • 原文地址:https://www.cnblogs.com/chenhs/p/1777635.html
Copyright © 2020-2023  润新知