2011-10-04 116 views
0

每當我嘗試通過服務管理器停止服務時,出現以下錯誤並且服務仍處於啓動狀態。 「無法停止本地計算機上的服務,該服務沒有返回錯誤,這可能是Windows內部錯誤或內部服務錯誤。」 我在這個問題上遇到過這樣的麻煩,我試圖儘可能地遵循微軟的邏輯。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb540474(v=vs.85).aspx 在.net 1.1中有類似的問題,你會發現,如果你搜索;不過,我根本沒有使用framweork。我的服務不會停止

void WINAPI serviceCtrlHandler(DWORD dwCtrl) 
{ 

    switch(dwCtrl) 
    { 
     case SERVICE_CONTROL_STOP: 
      ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); 
      SetEvent(stopEvent); 
      ReportSvcStatus(serviceStatus->dwCurrentState, NO_ERROR, 0); 

      return; 
     case SERVICE_CONTROL_INTERROGATE: 
      break; 
     default: 
      break; 
    } 
} 

void WINAPI startMain(DWORD argc, LPTSTR *argv) 
{ 
    serviceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, serviceCtrlHandler); 

    serviceStatus->dwServiceType = SERVICE_WIN32_OWN_PROCESS; 
    serviceStatus->dwServiceSpecificExitCode = NO_ERROR; 

    if (serviceStatusHandle == 0) 
    { 
     debug->DebugMessage(L"RegisterServiceCtrlHandler() failed, error: " + Error::GetErrorMessageW(GetLastError())); 
     return; 
    } 

    ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); 

    if (!SetServiceStatus(serviceStatusHandle, serviceStatus)) 
    { 
     //debug->DebugMessage(L"SetserviceStatus() failed, error: " + Error::GetErrorMessageW(GetLastError())); 
     //return; 
    } 

    stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 

    ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); 

    boost::thread dust_main_thread(dust_main); 

    while(1) 
    { 
     WaitForSingleObject(stopEvent, INFINITE); 

     ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); 
     return; 
    } 

} 

VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) 
{ 
    static DWORD dwCheckPoint = 1; 

    serviceStatus->dwCurrentState = dwCurrentState; 
    serviceStatus->dwWin32ExitCode = dwWin32ExitCode; 
    serviceStatus->dwWaitHint = dwWaitHint; 

    if (dwCurrentState == SERVICE_START_PENDING) 
     serviceStatus->dwControlsAccepted = 0; 
    else serviceStatus->dwControlsAccepted = SERVICE_ACCEPT_STOP; 

    if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) 
     serviceStatus->dwCheckPoint = 0; 
    else 
     serviceStatus->dwCheckPoint = dwCheckPoint++; 

    SetServiceStatus(serviceStatusHandle, serviceStatus); 
} 
+0

什麼是boost :: thread dust_main_thread(dust_main);做什麼?它是循環還是產生另一個線程? – user957902

+0

它等待包含管道連接並處理請求。無論哪種方式,我都應該能夠把那條線從那裏拿出來,它應該永遠等待停止事件。 – Bluebaron

+0

我假設serviceStatus變量是一個全局的,因爲我沒有看到它聲明。 SetEvent後面的下一行是報告serviceStatus-> dwCurrentState的值。但是,由於SetEvent之後的執行順序沒有保證,因此可能會根據線程上下文切換的位置再次報告SERVICE_STOPPED,然後再報告SERVICE_STOPPED_PENDING。 – user957902

回答

0

運行該服務,然後將調試器附加到正在運行的進程。在serviceCtrlHandler和WaitForSingleObject(stopEvent,INFINITE)之後放置一個斷點 - 確保你認爲應該發生的事情。

+0

好的。我將不得不在遠程計算機上安裝VS以獲得遠程調試器。 BBIAW。 – Bluebaron

+0

問題是我的一個問題。遠程調試爲我解決了這個問題。問題是,當我的服務自然結束時,它會調用serviceCtrlHandler(SERVICE_STOP);這應該是serviceCtrlHandler(SERVICE_CONTROL_STOP); 這導致程序退出而不通知SCM。 – Bluebaron

+0

@Bluebaron使用解決方案編輯原始問題,以便其他人可以從您的gaf中受益。 – Dennis