關於 ATL COM 開發中遇到的"ATL COM automation 服务器不能创建对象"問題


對微軟相當無語,自己搞了個插件框架,搞得想寫個通用的plugin蛋疼死,杯具啊,今天這個問題搞了我整整一天,網上幾乎沒相關提示,結果就是MS所謂的安全問題:

要讓你的控件是安全的。。。

#include <strsafe.h>
#include <ObjSafe.h>
HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription)
{
	ICatRegister *pcr = NULL ;
	HRESULT hr = S_OK ;

	hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
		NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
	if (FAILED(hr))
		return hr;

	// 确认HKCR\Component Categories\{..catid...}键值被注册

	CATEGORYINFO catinfo;
	catinfo.catid = catid;
	catinfo.lcid = 0x0409 ; // english

	size_t len;
	// 确认描述不是太长。
	// 只复制开始的127个字符。
	// StringCchLength的第二个参数表示被读入catDescription的最大字符数。
	// 第三个参数表示字符串的长度

	hr = StringCchLengthW(catDescription, STRSAFE_MAX_CCH, &len);
	if (SUCCEEDED(hr))
	{
		if (len>127)
		{
			len = 127;
		}
	}   
	else
	{
		// TODO: Write an error handler;

	}

	hr = StringCchCopyW(catinfo.szDescription, len + 1, catDescription);
	// 添加字符串结束符.
	catinfo.szDescription[len + 1] = '\0';

	hr = pcr->RegisterCategories(1, &catinfo);
	pcr->Release();

	return hr;
}

// HRESULT RegisterCLSIDInCategory -

//      注册组件分类信息


HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
	// 注册组件分类信息
	ICatRegister *pcr = NULL ;
	HRESULT hr = S_OK ;
	hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
		NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
	if (SUCCEEDED(hr))
	{
		CATID rgcatid[1] ;
		rgcatid[0] = catid;
		hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
	}

	if (pcr != NULL)
		pcr->Release();

	return hr;
}

// HRESULT UnRegisterCLSIDInCategory

HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
	ICatRegister *pcr = NULL ;
	HRESULT hr = S_OK ;

	hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
		NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
	if (SUCCEEDED(hr))
	{
		CATID rgcatid[1] ;
		rgcatid[0] = catid;
		hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
	}

	if (pcr != NULL)
		pcr->Release();

	return hr;
}

// DllRegisterServer - 将项添加到系统注册表
STDAPI DllRegisterServer(void)
{
    // 注册对象、类型库和类型库中的所有接口
    HRESULT hr = _AtlModule.DllRegisterServer();

	// 为初始化标记控件为安全控件                                       
	hr = CreateComponentCategory(CATID_SafeForInitializing, 
		L"Controls safely initializable from persistent data!");
	if (FAILED(hr))
		return hr; 
	hr = RegisterCLSIDInCategory(CLSID_SafeItem, 
		CATID_SafeForInitializing);
	if (FAILED(hr))
		return hr;
	// 为脚本标记控件为安全控件                                        
	hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely  scriptable!");
	if (FAILED(hr))
		return hr; 
	hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
	if (FAILED(hr))
		return hr;
	return hr;
}


// DllUnregisterServer - 将项从系统注册表中移除
STDAPI DllUnregisterServer(void)
{
	HRESULT hr = _AtlModule.DllUnregisterServer();

	hr=UnRegisterCLSIDInCategory(CLSID_SafeItem,                      CATID_SafeForInitializing);
	if (FAILED(hr))
		return hr; 
	hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, 
		CATID_SafeForScripting);
	if (FAILED(hr))
		return hr; 
	return hr;
}


你可能感兴趣的:(框架,server,服务器,脚本,null)