簡體   English   中英

Windows服務在啟動時不會輸入_tmain

[英]Windows service doesn't enter _tmain on startup

我正在基於以下頁面上的教程編寫服務: https : //www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus

我可以使用以下方法成功創建服務:

sc create service_name binPath=<path_name>

嘗試啟動服務時,出現以下錯誤:

sc start service_name
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.

這是我的main():

int main (int argc, char *argv[])
{
    OutputDebugString("service_name: entered main");
    SERVICE_TABLE_ENTRY ServiceTable[] = 
    {
        {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
        {NULL, NULL}
    };

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

    return 0;
}

編輯 :我從日志文件切換到OutputDebugString()/ DebugView

我運行了DebugView,但從未收到“ entered main”。 但是,如果我用return語句替換工作線程的內容,則確實可以成功啟動,並且會收到調試消息,因此我知道DebugView可以正常工作。

這是我創建工作線程的地方:

// Start a thread that will perform the main task of the service
HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
if (hThread) {
    // Wait until our worker thread exits, so we can set state to SERVICE_STOPPED and return needs to stop
    WaitForSingleObject (hThread, INFINITE);
} else {
    OutputDebugString("service_name: ServiceMain: CreateThread returned NULL");
}

看來我的工作線程是造成啟動錯誤的原因,但是為什么我不能在main()的頂部獲得調試消息?

如果服務創建成功,則應該在Windows服務列表中(計算機管理->服務和應用程序->服務)看到它。 如果不存在,則未正確注冊。 如果存在,則可以嘗試從Windows服務控制台啟動它。 您的_tmain不會被服務調用,不會生成任何日志。

您需要使用SetServiceStatus函數更新SCM狀態。

如果初始化服務需要很長時間,則應定期以SERVICE_START_PENDING狀態更新狀態。

初始化完成后,必須將SCM狀態更新為SERVICE_RUNNING。

其他狀態是:

-SERVICE_STOP_PENDING。

-SERVICE_PAUSE_PENDING。

-SERVICE_CONTINUE_PENDING。

-SERVICE_STOPPED。

我將狀態發送到SCM的函數如下:

BOOL SendStatusToSCM
                    (
                    DWORD dwCurrentState,
                    DWORD dwWin32ExitCode, 
                    DWORD dwServiceSpecificExitCode,
                    DWORD dwCheckPoint,
                    DWORD dwWaitHint
                    )
{
BOOL success;
SERVICE_STATUS serviceStatus;

// Preenche os campos do service status

serviceStatus.dwServiceType     = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState    = dwCurrentState;

if (dwCurrentState == SERVICE_START_PENDING)
    serviceStatus.dwControlsAccepted = 0;
else
    serviceStatus.dwControlsAccepted = 
        SERVICE_ACCEPT_STOP |
        SERVICE_ACCEPT_PAUSE_CONTINUE |
        SERVICE_ACCEPT_SHUTDOWN;

if (dwServiceSpecificExitCode == 0)
    serviceStatus.dwWin32ExitCode =
        dwWin32ExitCode;
else
    serviceStatus.dwWin32ExitCode = 
        ERROR_SERVICE_SPECIFIC_ERROR;
serviceStatus.dwServiceSpecificExitCode =
    dwServiceSpecificExitCode;

serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;

// Passa o status para o SCM

success = SetServiceStatus
                            (
                            serviceStatusHandle,
                            &serviceStatus
                            );
if (!success)
    exit( 99 );

return success;
}

通過以下創建,啟動服務可以完美運行並始終激活main():

serv = CreateService(

sc,

noServ,                     //  service name

noDisp,                     //  display name

SERVICE_ALL_ACCESS,         //  desired access

SERVICE_WIN32_OWN_PROCESS,  //  service type

SERVICE_AUTO_START,         //  modo de iniciar o serviço

SERVICE_ERROR_NORMAL,       //  gravidade da falha do serviço

noExec,                     //  nome do executável

NULL,                       //  nome do grupo ao qual pertence

NULL,                       //  tag id

NULL,                       //  tabela de dependências

NULL,                       //  account name 

NULL                        //  account password

);

暫無
暫無

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

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