// 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 

 

 

 

posted on 2010-07-14 23:11  大熊猫  阅读(364)  评论(0编辑  收藏  举报