Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. ATL 7.0 & NT Service.

ATL 7.0 & NT Service.

Scheduled Pinned Locked Moved C / C++ / MFC
c++visual-studioquestionlearning
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Carl
    wrote on last edited by
    #1

    Can anyone tell me what (obvious to everyone else) piece I'm missing? The following code doesn't work when run as a service. It runs fine when run through the IDE. All it does is set a timer. The SetTimer returns a valid number, but the TimerProc callback is never hit. Any ideas? Carl /////////////////////////////////////////////////////////////////////////// [ module(SERVICE, uuid = "{99CCA443-725A-44F2-A5F3-9855AFACF970}", name = "QService", helpstring = "QService 1.0 Type Library", resource_name="IDS_SERVICENAME") ] class CQServiceModule { public: CQServiceModule() {}; public: HRESULT PreMessageLoop(int nShowCmd) { HRESULT hr = __super::PreMessageLoop(nShowCmd); if ( SUCCEEDED(hr) ) return S_OK; return hr; } HRESULT Start(int nCmd) { m_lTimer = (UINT)::SetTimer((HWND) NULL, 1, 10000, TimerProc); return __super::Start(nCmd); } static void CALLBACK TimerProc(HWND hwnd,UINT uMsg, UINT idEvent, DWORD dwTime) { _AtlModule.LogEvent(_T("TimerEvent")); } UINT m_lTimer; };

    T 1 Reply Last reply
    0
    • C Carl

      Can anyone tell me what (obvious to everyone else) piece I'm missing? The following code doesn't work when run as a service. It runs fine when run through the IDE. All it does is set a timer. The SetTimer returns a valid number, but the TimerProc callback is never hit. Any ideas? Carl /////////////////////////////////////////////////////////////////////////// [ module(SERVICE, uuid = "{99CCA443-725A-44F2-A5F3-9855AFACF970}", name = "QService", helpstring = "QService 1.0 Type Library", resource_name="IDS_SERVICENAME") ] class CQServiceModule { public: CQServiceModule() {}; public: HRESULT PreMessageLoop(int nShowCmd) { HRESULT hr = __super::PreMessageLoop(nShowCmd); if ( SUCCEEDED(hr) ) return S_OK; return hr; } HRESULT Start(int nCmd) { m_lTimer = (UINT)::SetTimer((HWND) NULL, 1, 10000, TimerProc); return __super::Start(nCmd); } static void CALLBACK TimerProc(HWND hwnd,UINT uMsg, UINT idEvent, DWORD dwTime) { _AtlModule.LogEvent(_T("TimerEvent")); } UINT m_lTimer; };

      T Offline
      T Offline
      Tomasz Sowinski
      wrote on last edited by
      #2

      AFAIK services do not have message loops - and message loop is required when you want to use SetTimer, even with a callback function. Use Sleep() or waitable timer instead of SetTimer. Tomasz Sowinski -- http://www.shooltz.com

      C 1 Reply Last reply
      0
      • T Tomasz Sowinski

        AFAIK services do not have message loops - and message loop is required when you want to use SetTimer, even with a callback function. Use Sleep() or waitable timer instead of SetTimer. Tomasz Sowinski -- http://www.shooltz.com

        C Offline
        C Offline
        Carl
        wrote on last edited by
        #3

        Thanks for the response. The ATL service code includes 3 methods PreMessageLoop(); RunMessageLoop(); PostMessageLoop(); Which lead me to think (incorrectly?) that this should work. It worked with the ATL code with version 6.0, although a lot of the code that had been explicitely generated before is now contained in CAtlServiceModuleT.

        C 1 Reply Last reply
        0
        • C Carl

          Thanks for the response. The ATL service code includes 3 methods PreMessageLoop(); RunMessageLoop(); PostMessageLoop(); Which lead me to think (incorrectly?) that this should work. It worked with the ATL code with version 6.0, although a lot of the code that had been explicitely generated before is now contained in CAtlServiceModuleT.

          C Offline
          C Offline
          C J Berg
          wrote on last edited by
          #4

          First, a service is a normal Windows 32 program, and as such it has at least a system message queue (even if it doesn't use it). Each thread may also have a thread specific message queue, but the creation is deferred until it's really needed (e.g., a User or GDI function is called). The old SetTimer function makes use of window messages (it was normally used for background processing purposes back in the 16-bit days), even if you specify a callback. Because of this reason, one must get and dispatch messages when it's used. Basically, all you need to do is to implement a Get-or-Peek/DispatchMessage-loop somewhere in your ServiceMain (or a function called from it). This is what makes the wheel go round. MFC and other framework libraries have a message loop buried way down in their private code, so you don't see it often these days, but it's still integral to Windows. However, if the only WM-based function you're going to be using is SetTimer, there is a better solution: Waitable Timers. A waitable timer is a kernel object that can be waited on using the WaitForXObject(s) set of functions (cf. CreateWaitableTimer API), and it can be set to an absolute or relative due time. This way you can combine it with waiting on other events such as a Quit event, which is a good service design.

          C 1 Reply Last reply
          0
          • C C J Berg

            First, a service is a normal Windows 32 program, and as such it has at least a system message queue (even if it doesn't use it). Each thread may also have a thread specific message queue, but the creation is deferred until it's really needed (e.g., a User or GDI function is called). The old SetTimer function makes use of window messages (it was normally used for background processing purposes back in the 16-bit days), even if you specify a callback. Because of this reason, one must get and dispatch messages when it's used. Basically, all you need to do is to implement a Get-or-Peek/DispatchMessage-loop somewhere in your ServiceMain (or a function called from it). This is what makes the wheel go round. MFC and other framework libraries have a message loop buried way down in their private code, so you don't see it often these days, but it's still integral to Windows. However, if the only WM-based function you're going to be using is SetTimer, there is a better solution: Waitable Timers. A waitable timer is a kernel object that can be waited on using the WaitForXObject(s) set of functions (cf. CreateWaitableTimer API), and it can be set to an absolute or relative due time. This way you can combine it with waiting on other events such as a Quit event, which is a good service design.

            C Offline
            C Offline
            Carl
            wrote on last edited by
            #5

            Thank you for responding to my query. I always appreciate it when people take the time to help. The Run() method in AtlServiceModule calls this method void RunMessageLoop() throw() { MSG msg; while (GetMessage(&msg, 0, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } } and I have checked and made sure this is being hit. As to only using a timer, my service is instantiating a COM object that uses WinSock messages (that weren't processed either). I have since written my own WinSock module that uses overlapped IO, but I am rather stubborn and would like to know WHY this code doesn't work. Timers worked fine in a service generated under VC6. Again, I'd like to thank the people that have responded to my query. I posted the same question in a newsgroup and no one responded.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups