2016-10-18 3 views
0

이전 ATL 마법사의 기본 구조 (_tWinMain(), Run(), RunMessageLoop() 등)가 포함 된 이전 ATL 기반 서비스의 C++ 코드를 상속 받았습니다.PreShutdown 이벤트를 ATL 서비스에 추가하는 방법은 무엇입니까?

특히이 코드는 "Shutdown"및 "Stop"이벤트를 처리하며 "PreShutdown"이벤트에 추가 종료 항목을 추가하라는 요청을 받았습니다. 나는 SERVICE_ACCEPT_PRESHUTDOWN 옵션을 추가 한

.. 나는 결과 이벤트를 잡으려고 볼 수 없습니다 ..하지만

m_status.dwControlsAccepted |= SERVICE_ACCEPT_PRESHUTDOWN 

- SERVICE_CONTROL_PRESHUTDOWN을 - ATL은 "OnShutdown"와 "으로 onClose"을 제공하기 위해 나타나는 하지만 "OnPreShutdown"항목을 볼 수는 없습니다.

누구나 내가 기존 코드에 OnPreShutdown을 추가 할 수있게 해줄 수 있습니까?

답변

1

가장 큰 문제는 ATL이 RegisterServiceCtrlHandler 대신 RegisterServiceCtrlHandlerEx 사용한다는 것입니다; 두 번째 것만이 실제로 SERVICE_CONTROL_PRESHUTDOWN 메시지를 등록합니다. 또한 ATL에는 OnPreShutdown()에 대한 상속 가능한 템플릿이 없습니다.

용액 따라서 네 부분이다

(1) SERVICE_ACCEPTED_PRESHUTDOWN 메시지를 포함하는 수락 제어 메시지의 목록을 업데이트. SERVICE_ACCEPTED_SHUTDOWN은 Windows가 사전 종료를 처리 한 후에 서비스가 종료 된 것으로 간주하므로이 메시지를받지 못할 수 있으므로 제거 할 수 있습니다. 내가 변경

: m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;

사람 : 내 경우에는 변경은 무시 PreMessageLoop() 방법에 설정 제어 목록에 있었다이 메소드를 오버라이드 (override)하지 않았을 수 그러나 m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN;

- 그래서 당신은 단순히해야 이 값을 설정하는 모든 지점에서 해당 목록을 변경하십시오. (IInspectable는 (다른 답을 참조)을 고려 생성자 권장합니다.)

(2) ServiceMain() 무시 코드를 복제하고 RegisterServiceCtrlHandlerEx를 사용하도록 업데이트하여 완전히 교체.주요 변경 사항은 다음과 같습니다

변경 : m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);

에 : m_hServiceStatus = RegisterServiceCtrlHandlerEx(m_szServiceName, (LPHANDLER_FUNCTION_EX)_Handler, NULL);

하지만 당신은 또한 템플릿 코드를 제거하기 위해 this을 할 pTT에 대한 참조를 변경해야합니다 (당신은 또한 제거 할 수 있습니다 라인은 pT을 정의 함);

변경 : hr = T::InitializeCom();

사람 : 예를 들어 hr = this->InitializeCom();

(이 RegisterServiceCtrlHandler 호출을 포함하는 것처럼) 하지 기본 클래스에 대한 호출을 포함 마십시오.

(3) 덮어 쓰기 및 확장 Handler(). 이 같은 새로운 코드를 추가해야합니다 : (.이 비트에 올바른 방향으로 날 가리 도와 주셔서 IInspectable 덕분에 (다른 대답을 참조))

void CServiceModule::Handler(_In_ DWORD dwOpcpde) throw() 
{ 
    switch (dwOpcode) 
    { 
     case SERVICE_CONTROL_PRESHUTDOWN: 
      this->OnPreShutdown(); 
      break; 

     default: 
      __super::Handler(dwOpcode); 
      break; 
    } 
} 

을 (4)

당신이 할 수있는 Windows가 당신이 그것을 사용하는 경우 서비스가 사전 종료시 중지하고, 위의 구현되면 서비스가 어떤을받을 것으로 기대

void CServiceModule::OnPreShutdown() throw() 
{ 
    // custom handling code 
    // ... 

    // note: service must shutdown in this handler, so finish 
    //  by notifying this to SCM. 
    SetServiceStatus(SERVICE_STOPPED); 
} 

참고 : 지금 OnPreShutdown() 메소드를 구현메시지 (이미 종료 된 상태 여야 함) Windows에서 다른 서비스를 계속 종료하려면 OnPreShutdown() 메서드가 끝나면 SetServiceStatus(SERVICE_STOPPED) 최종 호출을 추가해야합니다.

+0

결론은 다음과 같습니다. ATL에 [features] (https : // msdn.microsoft.com/en-us/library/windows/desktop/ms685058.aspx). Windows XP/Server 2003 이후로 많이 사용되었습니다. 조금 슬픈 일입니다. 그래도 분석과 솔루션에 대한 좋은 직장입니다. – IInspectable

1

ATL을 사용한 서비스 구현은 ATL Services입니다. 기본 ATL 생성 서비스에서 제어 요청을 처리하지 않으려면 기본 생성 Handler 구현을 확장해야합니다.

이것은 당신이 (당신이 이미 제어 요청에 등록 이외에) 무엇을해야하는지에 대한 대략적인 스케치입니다 :

void CMyServiceModule::Handler(DWORD dwOpcode) throw() { 
    if (SERVICE_CONTROL_PRESHUTDOWN == dwOpcode) { 
     // Perform custom handling 
    } 
    else { 
     // Pass all other control codes to default implementation 
     __super::Handler(dwOpcode); 
    } 
} 

대안으로, 당신의 OnUnknownRequest 멤버를 오버라이드 (override) 할 수 귀하 맞춤 구현. 이 멤버는 기본 구현에 의해 처리되지 않은 모든 코드에 대해 호출됩니다

void CMyServiceModule::OnUnknownRequest(DWORD dwOpcode) { 
    if (SERVICE_CONTROL_PRESHUTDOWN == dwOpcode) { 
     // Perform custom handling 
    } 
    else { 
     // Possibly handle other control codes 
    } 
} 
+0

먼저 답해 주셔서 감사합니다. 둘째, 위에서 설명한 방식대로 처리기를 재정의하려했지만 "사용자 지정 처리"블록을 입력하지 않았습니다. PRESHUTDOWN을 사용하면 RegisterServiceCtrlHandlerEx 대신에 RegisterServiceCtrlHandler가 내장되어 있기 때문에 ServiceMain을 재정의해야 할 수도 있습니다 (이는 preshutdown 제어 메시지에 필요합니다). OnUnknownRequest를 자세히 살펴보고 메시지를받을 수 있는지 확인합니다. – n4m16

+0

OnUnknownRequest에서 사전 종료 제어 메시지를받지 못했습니다. (아마도 RegisterServiceCtrlHandlerEx를 통해 HandlerEx 대신 RegisterServiceCtrlHandler를 통해 Handler를 사용하는 ATL 때문일 수 있지만 100 % 확실하지는 않습니다.) – n4m16

+0

@Nick : [documentation] (https://msdn.microsoft.com) /en-us/library/xt3s14t0.aspx), 생성자에'm_status.dwControlsAccepted | = SERVICE_ACCEPT_PRESHUTDOWN; '을 추가해야합니다. 다른 시간에 설정하는 것은 잠재적으로 너무 늦습니다. 당신이 당신의 질문에 언급하지 않았기 때문에 당신은'm_status' 멤버를 어디에서 업데이트 했습니까? – IInspectable