如何在VS2005中开发ATL服务器

      以前一直使用VC6.0来开发ATL服务, 最近开始使用VS2005来开发,结果看到向导生成的框架后傻了眼,根本找不到以前熟悉的void CServiceModule::Run()函数了,VS2005生成的整个框架如下:

#include "stdafx.h"
#include "resource.h"
#include "XXXAgent.h"

#include <stdio.h>
#include "MainThread.h"

class CXXXAgentModule : public CAtlServiceModuleT< CXXXAgentModule, IDS_SERVICENAME >
{
public :
 DECLARE_LIBID(LIBID_XXXAgentLib)
 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_XXXAGENT, "{87BB17B1-D004-4888-A761-8917116F337D}")
 HRESULT InitializeSecurity() throw()
 {
  // TODO : 调用 CoInitializeSecurity 并为服务提供适当的
  // 安全设置
  // 建议 - PKT 级别的身份验证、
  // RPC_C_IMP_LEVEL_IDENTIFY 的模拟级别
  // 以及适当的非 NULL 安全说明符。
  
  return S_OK;
 }

 };

CXXXAgentModule _AtlModule;

//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    return _AtlModule.WinMain(nShowCmd);
}

    经过查阅资料后发现,在VS2005中,只需要重载PreMessageLoop和PostMessageLoop即可,PostMessageLoop函数里可以完成服务退出时的资源清理工作,PreMessageLoop函数里可以启动自己的线程来完成服务工作,也就是直接将以前在Run函数里所做的工作一样直接复制到这里即可. 新的框架如下:

#include "stdafx.h"
#include "resource.h"
#include "XXXAgent.h"

#include <stdio.h>
#include "MainThread.h"

class CXXXAgentModule : public CAtlServiceModuleT< CXXXAgentModule, IDS_SERVICENAME >
{
public :
 DECLARE_LIBID(LIBID_XXXAgentLib)
 DECLARE_REGISTRY_APPID_RESOURCEID(IDR_XXXAGENT, "{87BB17B1-D004-4888-A761-8917116F337D}")
 HRESULT InitializeSecurity() throw()
 {
  // TODO : 调用 CoInitializeSecurity 并为服务提供适当的
  // 安全设置
  // 建议 - PKT 级别的身份验证、
  // RPC_C_IMP_LEVEL_IDENTIFY 的模拟级别
  // 以及适当的非 NULL 安全说明符。
  
  return S_OK;
 }

 HRESULT CXXXAgentModule::PreMessageLoop(int nShowCmd) throw()
 {
  HRESULT hr = __super::PreMessageLoop(nShowCmd);
  if (SUCCEEDED(hr) && !m_bDelayShutdown)
   hr = CoResumeClassObjects();

  if (SUCCEEDED(hr))
  {
   //开始初始化并启动服务器主线程
   CMainThread MainThr;
   if(!MainThr.Init())
   {
    LogEvent(_T("UpdateServer Service OnInit() error."));
    ::MessageBox(NULL, _T("服务器初始化失败.../r/n"), _T("系统错误"), MB_OK+MB_ICONSTOP);
    RevokeClassObjects();
    return S_FALSE;
   }

   if(!MainThr.Run())
   {
    LogEvent(_T("UpdateServer Service OnRun() error."));
    ::MessageBox(NULL, _T("服务器启动失败.../r/n"), _T("系统错误"), MB_OK+MB_ICONSTOP);
    RevokeClassObjects();
    return S_FALSE;
   }
  }

  return hr;
 }

 
 HRESULT  CXXXAgentModule::PostMessageLoop() throw()
 {
  HRESULT hr = __super::PostMessageLoop();
  if (SUCCEEDED(hr))
  {
   // Add any custom code to uninitialize your service

  }

  return hr;
 }
};

CXXXAgentModule _AtlModule;

//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    return _AtlModule.WinMain(nShowCmd);
}

    那么如何重新设置服务的名称和描述信息呢,可以通过重载RegisterAppId函数来实现,具体如下:

HRESULT RegisterAppId(bool bService = false) throw()
    {          
  HRESULT hr = S_OK;
  BOOL res = __super::RegisterAppId(bService);
  if (bService)
  {
   if (IsInstalled())
   {       
    SC_HANDLE hSCM = ::OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
    SC_HANDLE hService = NULL;
    if (hSCM == NULL)
     hr = AtlHresultFromLastError();
    else
    {
     hService = ::OpenService(hSCM, m_szServiceName, SERVICE_CHANGE_CONFIG);
     if (hService != NULL)
     {
      TCHAR szDisplayName[128];
      ZeroMemory(szDisplayName, 128);
      lstrcpy(szDisplayName, _T("XXX代理服务器"));
      ::ChangeServiceConfig(hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, NULL, NULL, NULL, NULL, NULL, NULL, NULL, szDisplayName);
 
      SERVICE_DESCRIPTION Description;
      TCHAR    szDescription[1024];
 
      ZeroMemory(szDescription, 1024);
      ZeroMemory(&Description, sizeof(SERVICE_DESCRIPTION));
      lstrcpy(szDescription, _T("XXX软件有限公司 版权所有(R) 2001-2008"));
      Description.lpDescription = szDescription;
      ::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &Description);

      ::CloseServiceHandle(hService);
     }
     else
      hr = AtlHresultFromLastError();

     ::CloseServiceHandle(hSCM);
    }

   }
  }
  return hr;
     }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值