2011-10-04 115 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