您的位置:首页 > 其它

编写在浏览器中不弹出警告的ActiveX控件

2009-06-05 05:11 169 查看
我们在编写ActiveX控件时,如果用在浏览器中,经常都会弹出现在运行的脚本不安全的提示, 如果给客户使用,将会带来极大不便。按照MSDN的介绍通常有两种一种是实现IObjectSafe接口,一种是通过修改注册表的方法。一般如果用ATL开发ActiveX控件,就用实现ObjectSafe接口的方法。如果用MFC开发,我觉得还是用修改注册表的方法比较方便。下面我们将第二种方法:

要包括两个文件

#include "comcat.h"
#include "Objsafe.h"

// 本控件的CLSID,注册表用

const GUID CDECL CLSID_SafeItem =
{ 0x7AE7497B, 0xCAD8, 0x4E66, { 0xA5,0x8B,0xDD,0xE9,0xBC,0xAF,0x6B,0x61 } };

// 创建组件种类

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;

// Make sure the HKCR/Component Categories/{..catid...}
// key is registered.
CATEGORYINFO catinfo;
catinfo.catid = catid;
catinfo.lcid = 0x0409 ; // english

// Make sure the provided description is not too long.
// Only copy the first 127 characters if it is.
int len = wcslen(catDescription);
if (len>127)
len = 127;
wcsncpy(catinfo.szDescription, catDescription, len);
// Make sure the description is null terminated.
catinfo.szDescription[len] = ''/0'';

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

return hr;
}

// 注册组件种类

HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
ICatRegister* pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
// Register this category as being "implemented" by the class.
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}

// 卸载组件种类

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))
{
// Unregister this category as being "implemented" by the class.
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
}

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

return hr;
}

// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
HRESULT hr;

AFX_MANAGE_STATE(_afxModuleAddrThis);

if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);

if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);

// 标记控件初始化安全.
// 创建初始化安全组件种类
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 NOERROR;
}

// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
HRESULT hr;

AFX_MANAGE_STATE(_afxModuleAddrThis);

if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);

if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);

// 删除控件初始化安全入口.
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
// 删除控件脚本安全入口
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
return hr;

//////////////////////////
return NOERROR;
}


(全文完)


如果在本地使用ocx,那么需要人工注册,这种情况下您自己完全可以控制ocx的安全,如果想用,那么您就认为他是安全的了。

如果在internet上用,则一定要数字签名,所以控件的安全由数字签名来保证! ( rainsoft 发表于 2003-7-2 16:49:00)


如果说实现了这个接口就不会出提示,那么不是想做什么都可以,可以随意控制客户端的机器?逻辑上是可能的吗? ( zerochang 发表于 2003-7-1 11:31:00)


这个好像不好用呀。没有注册过的机器不行。我试了。
那位可以的可以给我个例子吗?lrcstar@sina.com
我再想如果,真的可以隐式下载,那WIN系统岂不是很不安全了吗?如何去控制恶意代码?晕!!! ( lrcstar 发表于 2003-6-30 21:34:00)


希望楼主总结一下他们的观点。 ( sander 发表于 2003-6-28 19:28:00)


不加入数字签名,IE会禁止下载,
那样只能够保证下载后在本机执行时不弹出
警告。
实现IObjectSafet接口
添加到类别:
BEGIN_CATEGORY_MAP(Cctrl)
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP() ( xwtwho 发表于 2003-6-27 14:11:00)


就话新说。。。。 ( zfive5 发表于 2003-6-27 13:06:00)


我在一本实例书上看见过,好象不买证书签名还是不行的 ( peterlcm 发表于 2003-6-27 10:56:00)


控件下载前代码不会被执行
需要在控件中实现IObjectSafety接口
在网上搜索一下就行了 ( 家宝 发表于 2003-6-27 10:44:00)


呵呵,偶前两天为这个问题困扰,才做过。方法一样,不过我的注册和卸载函数在BOOL CGraphView2ZTCtrl::CGraphView2ZTCtrlFactory::UpdateRegistry(BOOL bRegister)里面添加的,效果一样,不会有安全提示,^_^ ( warmchang 发表于 2003-6-27 9:32:00)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: