簡體   English   中英

如何在一個程序中運行多個 Windows 服務

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

我需要在一個程序中運行兩個不同的服務。 當我嘗試只執行一項服務時,我可以啟動另一項我無法啟動的服務。

下面是代碼:

這是我注冊為入口點的 servicemain:

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;
}

這是第二個入口點:

 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;
    } 

以下是我的調用方式:

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;
}

請幫助我,我是 C++ 編程的新手。

下面是服務控制處理程序:

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);

您尚未顯示ServiceCtrlHandler的代碼,但正如我所見,您對這兩個服務使用相同的 proc(這可能是您的錯誤所在)。 操作系統使用此過程來啟動/停止等您的服務,因此您必須相應地對其進行編碼。 完成后,您將能夠使用控制面板等啟動/停止您的任何服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM