DLLUnregister Server in MFC based COM applications | CodeGuru

DLLUnregister Server in MFC based COM applications

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Dec 1, 1998
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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 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

Download source –
[DllUnregisterServer_MFC_Impl.zip] – 1.3 KB

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.