简体   繁体   中英

how to run more than one windows service in a single program

I need to run two different services in a single program. When I try to do this only one service I am able to start the other one I am unable to start.

Below is the code:

This is the servicemain which I register as entry point:

VOID WINAPI ServiceMain1 (DWORD argc, LPTSTR *argv)
{
    DWORD Status = E_FAIL;

    // Register our service control handler with the SCM
    g_StatusHandleEA3 = RegisterServiceCtrlHandler (EA3_SERVICE_NAME, ServiceCtrlHandlerEA3);

    if (g_StatusHandleEA3 == NULL) 
    {
        goto EXIT;
    }

    // Tell the service controller we are starting
    ZeroMemory (&g_ServiceStatusEA3, sizeof (g_ServiceStatusEA3));
    g_ServiceStatusEA3.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
    g_ServiceStatusEA3.dwControlsAccepted = 0;
    g_ServiceStatusEA3.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatusEA3.dwWin32ExitCode = 0;
    g_ServiceStatusEA3.dwServiceSpecificExitCode = 0;
    g_ServiceStatusEA3.dwCheckPoint = 0;

    if (SetServiceStatus (g_StatusHandleEA3 , &g_ServiceStatusEA3) == FALSE)
    {
        OutputDebugString(_T(
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

    /*
     * Perform tasks necessary to start the service here
     */

    // Create a service stop event to wait on later
    g_ServiceStopEventEA3 = CreateEvent (NULL, TRUE, FALSE, NULL);
    if (g_ServiceStopEventEA3 == NULL) 
    {   
        // Error creating event
        // Tell service controller we are stopped and exit
        g_ServiceStatusEA3.dwControlsAccepted = 0;
        g_ServiceStatusEA3.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatusEA3.dwWin32ExitCode = GetLastError();
        g_ServiceStatusEA3.dwCheckPoint = 1;

        if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
    {
        OutputDebugString(_T(
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }
        goto EXIT; 
    }    

    // Tell the service controller we are started
    g_ServiceStatusEA3.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatusEA3.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatusEA3.dwWin32ExitCode = 0;
    g_ServiceStatusEA3.dwCheckPoint = 0;

    if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
    {
        OutputDebugString(_T(
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

    // Start a thread that will perform the main task of the service
    HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

    // Wait until our worker thread exits signaling that the service needs to stop
    WaitForSingleObject (hThread, INFINITE);


    /*
     * Perform any cleanup tasks 
     */

    CloseHandle (g_ServiceStopEventEA3);

    // Tell the service controller we are stopped
    g_ServiceStatusEA3.dwControlsAccepted = 0;
    g_ServiceStatusEA3.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatusEA3.dwWin32ExitCode = 0;
    g_ServiceStatusEA3.dwCheckPoint = 3;

    if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
    {
        OutputDebugString(_T(
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

EXIT:
    return;
}

This is the second entry point:

 VOID WINAPI ServiceMain2 (DWORD argc, LPTSTR *argv)
    {
        DWORD Status = E_FAIL;

        // Register our service control handler with the SCM
        g_StatusHandleEAT = RegisterServiceCtrlHandler (EAT_SERVICE_NAME, ServiceCtrlHandlerEAT);

        if (g_StatusHandleEAT == NULL) 
        {
            goto EXIT;
        }

        // Tell the service controller we are starting
        ZeroMemory (&g_ServiceStatusEAT, sizeof (g_ServiceStatusEAT));
        g_ServiceStatusEAT.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
        g_ServiceStatusEAT.dwControlsAccepted = 0;
        g_ServiceStatusEAT.dwCurrentState = SERVICE_START_PENDING;
        g_ServiceStatusEAT.dwWin32ExitCode = 0;
        g_ServiceStatusEAT.dwServiceSpecificExitCode = 0;
        g_ServiceStatusEAT.dwCheckPoint = 0;

        if (SetServiceStatus (g_StatusHandleEAT , &g_ServiceStatusEAT) == FALSE)
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }

        /*
         * Perform tasks necessary to start the service here
         */

        // Create a service stop event to wait on later
        g_ServiceStopEventEAT = CreateEvent (NULL, TRUE, FALSE, NULL);
        if (g_ServiceStopEventEAT == NULL) 
        {   
            // Error creating event
            // Tell service controller we are stopped and exit
            g_ServiceStatusEAT.dwControlsAccepted = 0;
            g_ServiceStatusEAT.dwCurrentState = SERVICE_STOPPED;
            g_ServiceStatusEAT.dwWin32ExitCode = GetLastError();
            g_ServiceStatusEAT.dwCheckPoint = 1;

            if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }
            goto EXIT; 
        }    

        // Tell the service controller we are started
        g_ServiceStatusEAT.dwControlsAccepted = SERVICE_ACCEPT_STOP;
        g_ServiceStatusEAT.dwCurrentState = SERVICE_RUNNING;
        g_ServiceStatusEAT.dwWin32ExitCode = 0;
        g_ServiceStatusEAT.dwCheckPoint = 0;

        if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }

        // Start a thread that will perform the main task of the service
        HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread1, NULL, 0, NULL);

        // Wait until our worker thread exits signaling that the service needs to stop
        WaitForSingleObject (hThread, INFINITE);


        /*
         * Perform any cleanup tasks 
         */

        CloseHandle (g_ServiceStopEventEAT);

        // Tell the service controller we are stopped
        g_ServiceStatusEAT.dwControlsAccepted = 0;
        g_ServiceStatusEAT.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatusEAT.dwWin32ExitCode = 0;
        g_ServiceStatusEAT.dwCheckPoint = 3;

        if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }

    EXIT:
        return;
    } 

Below is how I call:

int main()
{
    SERVICE_TABLE_ENTRY ServiceTable[] = 
    {
        {EA3_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain1},
        {EAT_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain2},
        {NULL, NULL}
    };

    if (StartServiceCtrlDispatcher (ServiceTable) == FALSE)
    {
        return GetLastError ();
    }

    return 0;
}

Please help me in this, I am new to c++ programming.

Below is the servicecontrolhandler:

VOID WINAPI ServiceCtrlHandlerEAT (DWORD CtrlCode)
{
    switch (CtrlCode) 
    {
     case SERVICE_CONTROL_STOP :

        if (g_ServiceStatusEAT.dwCurrentState != SERVICE_RUNNING) 
           break;

        /* 
         * Perform tasks necessary to stop the service here 
         */

        g_ServiceStatusEAT.dwControlsAccepted = 0;
        g_ServiceStatusEAT.dwCurrentState = SERVICE_STOP_PENDING;
        g_ServiceStatusEAT.dwWin32ExitCode = 0;
        g_ServiceStatusEAT.dwCheckPoint = 4;


        if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE) 
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
        }

        // This will signal the worker thread to start shutting down
        SetEvent (g_ServiceStopEventEAT);

        break;

     default:
         break;
    }
}  


VOID WINAPI ServiceCtrlHandlerEA3 (DWORD CtrlCode)
{
    switch (CtrlCode) 
    {
     case SERVICE_CONTROL_STOP :

        if (g_ServiceStatusEA3.dwCurrentState != SERVICE_RUNNING) 
           break;

        /* 
         * Perform tasks necessary to stop the service here 
         */

        g_ServiceStatusEA3.dwControlsAccepted = 0;
        g_ServiceStatusEA3.dwCurrentState = SERVICE_STOP_PENDING;
        g_ServiceStatusEA3.dwWin32ExitCode = 0;
        g_ServiceStatusEA3.dwCheckPoint = 4;


        if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE) 
        {
            OutputDebugString(_T(
              "My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
        }

        // This will signal the worker thread to start shutting down
        SetEvent (g_ServiceStopEventEA3);

        break;

     default:
         break;
    }
}  
RegisterServiceCtrlHandler (EA3_SERVICE_NAME, ServiceCtrlHandler);

You haven't shown your code for ServiceCtrlHandler but as I see you use the same proc for both services (and this is where your error could be). This proc is used by OS to start/stop etc. your service(s), so you have to code it accordingly. Once you're done you would be able to start/stop any of your services using control panel or such.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM