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

我们在编写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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值