MFC向层生成的COM中未实现DllUnregisterServer

关于DllUnregisterServer输出,通过MFC生成的COM未提供,必须自已手工做。ATL向导却有生成,不知为何。
COM   原理及应用中第5.2.4(160/page)有提到。
实现方法: 
方法 1:可采用MFC生成的OCX代码中的DllUnregisterServer函数。

方法2:取自 http://www.fltvu.com/jiaocheng/chenxu2/Visual%20C++/source%20code/Atl/DllUnregisterServer_MFC_Impl.shtml.htm

mfc usually saves you a lot of time when impelmenting com components. for example, mfc-based com dll projects generated with appwizard automatically provides you with the implementation of dllregisterserver function. however, there is no dllunregisterserver in the appwizard generated dll. this, generally, is not acceptable, because every com dll should support self-registration as well as self-unregistration.

mfc-based implementation of dllregisterserver() calls coleobjectfactory::updateregistryall(). this method has an undocumented parameter - (bool bregister = true) - so, we can expect that calling coleobjectfactory::updateregistry(false) will unregister com dll for us. this is, unfortunately, not the case. looking at the source code quikly tells us, that coleobjectfactory::updateregistryall(bool bregister) calls coleobjectfactory::updateregistry(bool bregister) passing the same value of bool parameter, but the implementation of coleobjectfactory::updateregistry(bool bregister) calls updateregistry(lpctstr lpszprogid) which registers dll only if bregister is true, otherwise it just does nothing!

therefore, it is still necessary to write our own dllunregisterserver(). the code below is a ready and easy to use implementation of dllunregisterserver() for mfc-based com dlls. to use it:

- create a file dllunregisterserver_mfc_impl.inl

- copy/paste the code below into this file

- add the following line at the end of the main dll .cpp file (dll_name.cpp):


#include "dllunregisterserver_mfc_impl.inl"

- add the following line to the exports section of the dll .def file (dll_name.def):

 
dllunregisterserver private

that's it! now you can use "regsvr32 /u dll_name.dll" for dll unregistration!

this code was tested with vc++ 5.0, vc++ 5.0 sp3, vc++ 6.0 (yeah, 6.0 still doesn't provide dllunregisterserver for free) in ansi builds. there should be no problems with unicode as well.


//**************************************************************************
// date : 11.15.98
// header : dllunregisterserver_mfc_impl.inl
//
// desc.: dllunregisterserver() helper for the inproc servers that were
//  registered via mfc's coleobjectfactory::updateregistryall()
//
// usage:
//   add '#include "dllunregisterserver_mfc_impl.inl"' to the end of
//  the main dll file (i.e. dll_name.cpp).
//
//   add 'dllunregisterserver private' to exports section of the
//  dll_name.def.
//
// caution:
//   code below uses undocumented, internal mfc data structures
//  and functions. therefore, probably, it will be necessary to modify
//  it, according to the changes in the future versions of mfc.
//   code below is based on the coleobjectfactory::updateregistryall(),
//  in src/olefact.cpp. (src/olereg.cpp - is actual implementation of
//  all registry work).
//**************************************************************************
#include "stdafx.h"

// workaround mfc bug - no #ifndef/#endif for afximpl.h header
#if !defined(crit_objectfactorylist)
#include <../src/afximpl.h>
#endif  //!crit_objectfactorylist
//**************************************************************************
static hresult unregistercomobject(refclsid p_clsid)
{
 lpolestr t_wzprogid(null);

 // get progid from clsid and unregister...
 hresult t_hr = ::progidfromclsid(p_clsid, &t_wzprogid);
 if(failed(t_hr))
  return t_hr;

 // convert olestr to lptstr
 cstring t_strprogid(t_wzprogid);
 lpctstr t_szprogid = t_strprogid.operator lpctstr();

 // free memory
 ::cotaskmemfree(t_wzprogid);

 // unregister...
 if(afxoleunregisterserverclass(p_clsid,
           t_szprogid,
           t_szprogid,
           t_szprogid,
           oat_dispatch_object))
  return s_ok;
 else
  return e_fail;
}
//**************************************************************************
// by exporting dllunregisterserver, you can use regsvr.exe
stdapi dllunregisterserver(void)
{
 afx_manage_state(afxgetstaticmodulestate());


 afx_module_state* pmodulestate = afxgetmodulestate();

 afxlockglobals(crit_objectfactorylist);
 for(coleobjectfactory* pfactory = pmodulestate->m_factorylist;
  pfactory != null;
  pfactory = pfactory->m_pnextfactory)
 {
  hresult t_hr = unregistercomobject(pfactory->getclassid());
  if(failed(t_hr))
  {
   afxunlockglobals(crit_objectfactorylist);
   return t_hr;
  }
 }
 afxunlockglobals(crit_objectfactorylist);

#ifdef _afxdll
 afxlockglobals(crit_dynlinklist);
 // register extension dll factories
 for(cdynlinklibrary* pdll = pmodulestate->m_librarylist;
  pdll != null;
  pdll = pdll->m_pnextdll)
 {
  for(pfactory = pdll->m_factorylist;
   pfactory != null;
   pfactory = pfactory->m_pnextfactory)
  {
   hresult t_hr = unregistercomobject(pfactory->getclassid());
   if(failed(t_hr))
   {
    afxunlockglobals(crit_dynlinklist);
    return t_hr;
   }
  }
 }
 afxunlockglobals(crit_dynlinklist);
#endif

 return s_ok;
}
//**************************************************************************
// end of dllunregisterserver_mfc_impl.inl

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值