分享
 
 
 

在基于MFC的组件程序中加入自卸载功能

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

作者:Alexei Evdokimov 译自:CodeGuru

使用MFC实现COM组件时,经常节省许多开发时间。例如,使用AppWizard生成的基于MFC的COM dll工程,已经自动的提供了DllRegisterServer功能的实现。然而,却没有自动生成DllUnregisterServer功能。一般情况下,DllUnregisterServer对于程序是不可缺少的,因为一个完整的程序,不仅需要自注册功能,同时也需要自卸载功能。

基于MFC实现DllRegisterServer()的方法是调用COleObjectFactory::UpdateRegistryAll()。这个方法有一个未公开的参数-(BOOL bRegister = TRUE) - 因此,我们猜测通过调用COleObjectFactory::UpdateRegistry(FALSE)将能够实卸载COM dll的功能。但是,事实并非如此。通过分析源代码,我们能够知道COleObjectFactory::UpdateRegistryAll(BOOL bRegister)通过同样的BOOL值调用COleObjectFactory::UpdateRegistry(BOOL bRegister),但是COleObjectFactory::UpdateRegistry(BOOL bRegister)的实现调用UpdateRegistry(LPCTSTR lpszProgID)函数,这个调用仅当bRegister为TRUE时注册组件,否则什么都不做!

所以,有必要写我们自己的DllUnregisterServer()。下面的代码能够实现基于MFC的DllUnregisterServer(),并且使用非常的简单。使用方法:

- 创建文件DllUnregisterServer_MFC_Impl.inl

- 把下面的代码拷贝/粘贴到新建的文件中

- 在dll的主文件.cpp中(dll_name.cpp)加入:

#include "DllUnregisterServer_MFC_Impl.inl"

- 在dll_name.def文件的EXPORTS片断中加入:

DllUnregisterServer PRIVATE

完成!现在你可以使用"regsvr32 /u dll_name.dll"完成组件的卸载了。

以下代码测试环境为VC++ 5.0, VC++ 5.0 SP3, VC++ 6.0,ANSI环境。也可用于UNICODE环境。

//**************************************************************************

// 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 ’DllUnregisterServerPRIVATE’ 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 srcolefact.cpp. (srcolereg.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 <..srcafximpl.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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有