atl servcie

atl servcie
2007-09-22 15:05

 

ATL Services :To create your ATL COM object so that it runs in a service, simply select Service (EXE) from the list of server options in the ATL Project Wizard. The wizard will then create a class derived from CAtlServiceModuleT to implement the service.

关于使用 VS.NET 2003 ATL7.0 创建NT Service 型COM服务器的问题!

用 ATL 编写 Windows 服务 : 有时候,我们需要自己写的程序在没有用户登陆的情况下,只要Windows系统启动就运行,那我们可以把我们的程序写成一个Windows服务。服务是能 够为各种用户(包括本地用户和远程用户)所用的,拥有用户授权级进行管理的能力,并且不论用户是否物理的与正在运行该应用程序的计算机相连都能正常执行。

Writing a Windows Service using ATL 7.1

After more than 12 years of C++ Windows development I have written my share of Windows Services. These days however I spend most my income generating time in the throws of .NET development and consulting. But every now and then I get to do some really cool task using C++, mostly real-time hardware interfaces.

Recently I had to develop a Windows Service and since the service is interacting with a hardware device I thought I would go with C++ rather than .NET. This would be the first non .NET Windows service I have developed in about 3 years. Of course I would have to dig out all my backups to find my tried and tested service framework. Then I thought since the service was really nothing special let me use the ATL framework to develop the service. Now ATL is a technology that I really had a handle on, but that was in the days of version 3 so what did version 7 have to offer?

I fired up Visual Studio and selected the Visual C++ ATL Project. From the ensuing wizard I selected the Application Settings tab and checked the Attributed checkbox and the Service (EXE) radio button. In the generated code I quickly came across the class that implemented the heart of the service, this is essentially a template class that derives from a specialization of CAtlServiceModuleT<> .

Looking through the code for the template class (this is in the file atlbase.h) I decided that the Run method was a good place to put the code that started the service, so to test my theory I made a call the the LogEvent utility function to log an event when the Run method was invoked. I compiled the service and registered it by executing the service with the /service command line argument. When I started the service the service started and immediately stop, some thing was up so I stepped through the code and found that the call to PreMessageLoop was not returning S_OK, in short the function was trying to register COM object, but I had not written and COM objects and nor was I intending to. Fortunately I noticed that Microsoft had place the code in a define _ATL_NO_COM_SUPPORT so I defined this in the stdafx.h file, recompiled and started the service, this time my services started and stayed that way. I could even stop my service without any problem. To indicated to the Service Control Manager (SCM) that the service can handle notifications other than Start/Stop I modified the m_status.dwControlsAccepted flag to include SERVICE_ACCEPT_PAUSE_CONTINUE and overrode the OnPause and OnContinue functions.

As it turns out building a standard Windows Service using ATL is very simple. In summary here are the steps I followed:1) Add the following code to the stdafx.h, before any of the #include statements
#define _ATL_NO_COM_SUPPORT


2) Add a constructor to the Module class, this class will be called CxxxModule where xxx is the name used when creating the project. In the constructor modify the m_status.dwControlsAccepted as required, here is an example that enables support for Pause and Continue.
m_status.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;


3) Override the Run method to start you service activities, ultimately this is called whenever the service is started. It is important that the base class implementation is called so that the message loop is started. A simple implementation would look like this.


          HRESULT Run(int nShowCmd = SW_HIDE)
          {
            // Start worker thread here
            return __super::Run(nShowCmd);
          }

4) Override OnStop to stop the service. Here you should stop your thread from running and call the base class OnStop which takes care of terminating the message loop and notifying the SCM that the service has stopped. If the process of stopping the service thread is time consuming then you need to take further steps to manage this, if there is enough interest I will cover this in a later post.


          void OnStop()
          {
            // Stop worker-thread
            __super::OnStop();
          }

5) Override whatever other handlers you have choosen to support eg. OnPause and OnContinue. In these overrides you should call the SetServiceStatus to update the SCM on the status of the service. For example a simple implementation of OnPause and OnContinue would be something like the following.


          void OnPause()
          {
            SetServiceStatus(SERVICE_PAUSE_PENDING);
            // Pause worker-thread activity
            SetServiceStatus(SERVICE_PAUSED);
          }

          void OnContinue()
          {
            SetServiceStatus(SERVICE_CONTINUE_PENDING);
            // Resume worker-thread activity
            SetServiceStatus(SERVICE_RUNNING);
          }

This is not intended as an introduction to implementing windows services, just a documentation of the steps required to implement a standard Windows service using ATL 7.1. I have not even mentioned message string resources etc. I only hope this is useful enough to get some started without having to dig around like I did.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值