VC++ Service编程(二)编写ServiceMain函数

来源:互联网 发布:网络和ip地址计算 编辑:程序博客网 时间:2024/06/07 12:09

编写ServiceMain函数

    下面例子中的MyServiceStart函数是这个服务的ServiceMain函数。MyServiceStart函数可以使用命令行参数,就像控制台程序中main函数那样的方式。第一个参数是传递给服务的值的个数,并且这个个数的最小值总是1。第二个参数是一个字符数组指针。数组的第一项总是当前服务的名称。

    MyServiceStart函数首先填充一个SERVICE_STATUS结构,其中包含它所要接受的控制请求代码。虽然这个服务接受SERVICE_CONTROL_PAUSE 和 SERVICE_CONTROL_CONTINUE,但在被要求停止的时候,并没有做什么重要的操作。包含SERVICE_ACCEPT_PAUSE_CONTINUE仅仅是为了举一个例子。如果服务暂停时并没有传递进来的参数,不要支持暂停。

    MyServiceStart函数马上调用RegisterServiceCtrlHandler函数,将MyService函数注册成为服务的控制请求处理函数,并且开始作初始化的工作。下面例子中的初始化函数——MyServiceInitialization,只是为了举个例;它没有做任何初始化的工作,比如说创建一个额外的线程。如果服务的初始化工作要花比一秒更长的时间,应该在代码里周期性的调用SetServiceStatus函数建立等待时间和检查点,来指示初始化工作正在进行。

    当初始化成功完成时,例子以SERVICE_RUNNING为参数调用SetServiceStatus函数,并且继续它自己的工作。如果在初始化的过程中遇到错误,则以SERVICE_STOPPED为参数调用SetServiceStatus函数,然后返回。

    因为例子并没有完成什么真的工作,所以它只是简单的将控制权返回给调用函数。让这个函数自己返回,而不是调用ExitThread函数很重要,因为返回时,可以清理为变量开辟的内存。

 

#include <windows.h>

 

SERVICE_STATUS          MyServiceStatus;

SERVICE_STATUS_HANDLE   MyServiceStatusHandle;

 

VOID SvcDebugOut(LPSTR String, DWORD Status);

 

void WINAPI MyServiceStart (DWORD argc, LPTSTR *argv)

{

    DWORD status;

    DWORD specificError;

 

    MyServiceStatus.dwServiceType        = SERVICE_WIN32;

    MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING;

    MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP |

        SERVICE_ACCEPT_PAUSE_CONTINUE;

    MyServiceStatus.dwWin32ExitCode      = 0;

    MyServiceStatus.dwServiceSpecificExitCode = 0;

    MyServiceStatus.dwCheckPoint         = 0;

    MyServiceStatus.dwWaitHint           = 0;

 

    MyServiceStatusHandle = RegisterServiceCtrlHandler(

        "MyService",

        MyServiceCtrlHandler);

 

    if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)

    {

        SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler

            failed %d ", GetLastError());

        return;

    }

 

    // Initialization code goes here.

    status = MyServiceInitialization(argc,argv, &specificError);

 

    // Handle error condition

    if (status != NO_ERROR)

    {

        MyServiceStatus.dwCurrentState       = SERVICE_STOPPED;

        MyServiceStatus.dwCheckPoint         = 0;

        MyServiceStatus.dwWaitHint           = 0;

        MyServiceStatus.dwWin32ExitCode      = status;

        MyServiceStatus.dwServiceSpecificExitCode = specificError;

 

        SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);

        return;

    }

 

    // Initialization complete - report running status.

    MyServiceStatus.dwCurrentState       = SERVICE_RUNNING;

    MyServiceStatus.dwCheckPoint         = 0;

    MyServiceStatus.dwWaitHint           = 0;

 

    if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))

    {

        status = GetLastError();

        SvcDebugOut(" [MY_SERVICE] SetServiceStatus error

            %ld ",status);

    }

 

    // This is where the service does its work.

    SvcDebugOut(" [MY_SERVICE] Returning the Main Thread ",0);

 

    return;

}

 

// Stub initialization function.

DWORD MyServiceInitialization(DWORD   argc, LPTSTR  *argv,

    DWORD *specificError)

{

    argv;

    argc;

    specificError;

    return(0);

}

0 0