分享

vc6和vs2003下ATL服务程序的区别

 noairman 2010-03-29

在VC++6与VC++.Net 2003中使用ATL开发Windows服务时,是有一些区别的。   
   其原因是VC++6与VC++.Net 2003中ATL的版本不同。
   VC++.Net 2003中,ATL的版本为7.0,用于处理Windows服务的部分已被封装。
   在VC++.Net 2003中使用ATL开发Windows服务的基本步骤如下:   
    
   1、创建ATL工程。在ATL工程向导中,选择“Application    Setting”,   
   服务器类型(Server    type)选择“Service(EXE)”,其中,“Attributed”我通常是不选的。
   工程创建完毕后,ATL工程向导将自动生成两个工程,“xxxx”和“xxxxPS”,    如:Test,    TestPS。
   通常我是删掉“xxxxPS”这个工程。      
   2、在ATL工程向导自动创建的类CxxxxModule中,重载CAtlServiceModuleT的两个方法:   
           PreMessageLoop、PostMessageLoop   
   其中,PreMessageLoop用于Windows服务启动前的初始化工作,并创建一个工作线程,以完成具体的处理。
   (启动服务将调用PreMessageLoop方法)。注意:重载PreMessageLoop方法时,必须返回S_OK。
     
   PostMessageLoop用于Windows服务停止后释放某些相关资源,并终止工作线程的运行。
         (停止服务时将调用PostMessageLoop方法)。   
    
   3、如果要对命令行参数进行处理,则重载ParseCommandLine方法。   
    
   下面是一个Windows服务的代码片段:   
    
   class    CTestModule    :    public    CAtlServiceModuleT<    CTestModule,    IDS_SERVICENAME    >   
   {   
   public    :   
   DECLARE_LIBID(LIBID_TestLib)   
   DECLARE_REGISTRY_APPID_RESOURCEID(IDR_Test,    "{CE42CD12-B8BD-44F3-9BC6-56CA0790E71B}")   
   HRESULT    InitializeSecurity()    throw()   
   {   
   //    TODO    :    Call    CoInitializeSecurity    and    provide    the    appropriate    security    settings    for   
   //    your    service   
   //    Suggested    -    PKT    Level    Authentication,   
   //    Impersonation    Level    of    RPC_C_IMP_LEVEL_IDENTIFY   
   //    and    an    appropiate    Non    NULL    Security    Descriptor.   
    
   return    S_OK;   
   }   
    
           //   
           //    在ATL    7.0中,用于处理Windows服务的部分已被封装。   
           //   
           //              通过重载PreMessageLoop与PostMessageLoop方法来初始化或释放   
           //      Windows服务的相关资源。   
           //   
           HRESULT    PreMessageLoop(int    nShowCmd)    throw()   
           {   
                   HRESULT    hr    =    S_OK;   
    
                   //   
                   //    启动服务的工作线程   
                   //   
                   hr=CAtlServiceModuleT<CTestModule,IDS_SERVICENAME>::PreMessageLoop(nShowCmd);    
                   memset(m_szServer,0,_MAX_PATH);   
                   m_dwPort=0;   
                   if(!m_Listener.Create(m_szServer,m_dwPort))   
                   {   
                           PrintMessage(_T("绑定网络地址%s:%d失败,请检查网络配置,服务终止。"),   
                                                           m_szServer,    m_dwPort    );   
                           return    E_FAIL;   
                   }   
    
                   //   
                   //    启动Socket监听线程   
                   //   
                   if(!m_Listener.Run())   
                   {   
                           PrintMessage(    _T("异常!服务线程启动失败,服务终止。")    );   
                           return    E_FAIL;   
                   }   
    
                   return    S_OK;   
           }   
    
           HRESULT    PostMessageLoop()    throw()   
           {   
                   HRESULT    hr    =    S_OK;   
                   hr=CAtlServiceModuleT<CTestModule,IDS_SERVICENAME>::PostMessageLoop();   
    
                   //   
                   //    终止Socket监听线程   
                   //   
                   m_Listener.Shutdown();   
                   return    hr;   
           }   
    
           bool    ParseCommandLine(LPCTSTR    lpCmdLine,HRESULT*    pnRetCode)    throw()   
           {   
                   bool          bResult;   
                   bResult    =    CAtlServiceModuleT<CTestModule,IDS_SERVICENAME>::ParseCommandLine(lpCmdLine,    pnRetCode);  

                   if(!bResult)   
                   {   
                           TCHAR    szTokens[] =    _T("-/");   
    
                           LPCTSTR    lpszToken= FindOneOf(lpCmdLine,szTokens);   
                           while    (lpszToken    !=    NULL)   
                           {   
                                   if    (WordCmpI(lpszToken,    _T("Service"))==0)   
                                   {   
                                           SetupRegistry();   
                                           break;   
                                   }   
                                   lpszToken    =    FindOneOf(lpszToken,    szTokens);   
                           }   
                   }   
    
                   return    bResult;   
           }   
   private:   
    
           CListener    m_Listener;   
           char         m_szServer[_MAX_PATH];   
           DWORD        m_dwPort;   
   };  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多