Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2915511
  • 博文数量: 355
  • 博客积分: 1241
  • 博客等级: 中尉
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-27 06:48
个人简介

下死功夫,动活脑筋;读好书,交益友

文章分类

全部博文(355)

文章存档

2020年(6)

2019年(16)

2018年(23)

2017年(67)

2016年(42)

2015年(51)

2014年(57)

2013年(52)

2012年(35)

2011年(5)

分类: WINDOWS

2012-03-30 15:33:31

最近一直写SSLVPN客户端,和10年前的项目类似,都是com调用com。
创建ATL Service,在PreMessageLoop函数中调用其他的com组件,出现CoInitialize not called (800401f0)。我记得类似的代码在vs2005中运行正常,经过两天的代码对比后,
class ATL_NO_VTABLE CAtlServiceModuleT :
 public CAtlExeModuleT
以前,com的初始化在CAtlExeModuleT的构造函数中作,
InitializeCom()函数从CAtlExeModuleT的构造函数,移到了CAtlExeModuleT::winmain(),但是 CAtlServiceModuleT::winmain,并没有调用InitializeCom()。
微软的专家给出了解决方案
在atlbase.h文件文件中CAtlServiceModuleT::Start中将
HRESULT Start(_In_ int nShowCmd) throw()
 {
  T* pT = static_cast(this);
  // Are we Service or Local Server
  CRegKey keyAppID;
  LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
  if (lRes != ERROR_SUCCESS)
  {
   m_status.dwWin32ExitCode = lRes;
   return m_status.dwWin32ExitCode;
  }
  CRegKey key;
  lRes = key.Open(keyAppID, pT->GetAppIdT(), KEY_READ);
  if (lRes != ERROR_SUCCESS)
  {
   m_status.dwWin32ExitCode = lRes;
   return m_status.dwWin32ExitCode;
  }
  TCHAR szValue[MAX_PATH];
  DWORD dwLen = MAX_PATH;
  lRes = key.QueryStringValue(_T("LocalService"), szValue, &dwLen);
  m_bService = FALSE;
  if (lRes == ERROR_SUCCESS)
   m_bService = TRUE;
  if (m_bService)
  {
   SERVICE_TABLE_ENTRY st[] =
   {
    { m_szServiceName, _ServiceMain },
    { NULL, NULL }
   };
   if (::StartServiceCtrlDispatcher(st) == 0)
    m_status.dwWin32ExitCode = GetLastError();
   return m_status.dwWin32ExitCode;
  }
  // local server - call Run() directly, rather than
  // from ServiceMain()
  m_status.dwWin32ExitCode = pT->Run(nShowCmd);
  return m_status.dwWin32ExitCode;
 }
改为
 if (::StartServiceCtrlDispatcher(st) == 0)
                m_status.dwWin32ExitCode = GetLastError();
            return m_status.dwWin32ExitCode;
        }
        // local server - call Run() directly, rather than
        // from ServiceMain()
        #pragma region Run wrapped by InitializeCom/UninitializeCom
        // FIX: See http://connect.microsoft.com/VisualStudio/feedback/details/582774/catlservicemodulet-winmain-coinitialize-not-called-800401f0
#ifndef _ATL_NO_COM_SUPPORT
        HRESULT hr = E_FAIL;
        hr = T::InitializeCom();
        if (FAILED(hr))
        {
            // Ignore RPC_E_CHANGED_MODE if CLR is loaded. Error is due to CLR initializing
            // COM and InitializeCOM trying to initialize COM with different flags.
            if (hr != RPC_E_CHANGED_MODE || GetModuleHandle(_T("Mscoree.dll")) == NULL)
                return hr;
        } else
            m_bComInitialized = true;
        m_status.dwWin32ExitCode = pT->Run(nShowCmd);
        if (m_bComInitialized)
            T::UninitializeCom();
#else
        m_status.dwWin32ExitCode = pT->Run(nShowCmd);
#endif
        #pragma endregion
        return m_status.dwWin32ExitCode;
    }
我一般不大愿意修改atl的代码,还是在
_tWinMain()函数中添加
 _AtlModule.InitializeCom();
经过确认,没有这行代码,release版本在退出时,也会有错误发生
阅读(3310) | 评论(0) | 转发(0) |
0

上一篇:和老婆聊facebook的事情

下一篇:nginx配置ssl

给主人留下些什么吧!~~