欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.Net魔法堂:史上最全的ActiveX开发教程——开发篇

程序员文章站 2022-04-14 10:28:52
一、前言                                     在设计某移动内部自动化运维平台时,经综合考虑终端机性能和功能需求等因素后,决定采用b/s模式,并...
一、前言                                

 

  在设计某移动内部自动化运维平台时,经综合考虑终端机性能和功能需求等因素后,决定采用b/s模式,并且通过activex实现与服务器agent作p2p的通讯。好处,整个平台以网页形式存在,界面渲染性能高于桌面应用(终端机性能其低);通过activex组件与各服务器agent进行p2p通讯,不对web服务器造成压力。风险,当用activex传输上百兆的文件时,会对浏览器造成哪些影响;团队中没有类似解决方案的经验供借鉴。解决方法:前期对主要功能进行快速原型设计、开发、验证和总结。

 

  本系列将记录从开发、部署、更新、卸载到activex与js间的交互的.net开发activex全过程。由于之前学习如何使用.net开发activex时,查找了不少文档,经过两天的东拼西凑后才掌握了整个开发过程,现在整理成系列以供日后查阅。

 

  下面我们一起按部就班写activex吧!

 

 

 

二、写代码咯!                              

 

  开发环境:win7、vs2010

 

  1. 创建类

 

  

 

  2. 设置工程属性

 

  2.1.  在应用程序页中,打开 程序集信息 ,勾选 使程序集com可见

 

      

 

  2.2.  在 生成 页中, 勾选 为com互操作注册

 

      

 

  2.3. 在 properties.assemblyinfo.cs文件中 添加 `[assembly:allowpartiallytrustedcallers()]`(注意引入:`system.security`命名空间)

 

      

 

 3. 添加用户控件

 

     activex以用户控件为载体,加载到网页中

 

 4. 添加控件的guid

 

   activex的用户控件均有一个独立的guid标识,该guid必须与工程的guid不同。

 

     4.1. 通过vs2010->工具->创建guid

 

     

 

    4.2. 引入`system.runtime.interopservices`

  4.3. 将生成的guid粘贴到用户控件类声明前

 

 [guid("4d39585b-7947-4197-8bdb-b0a6918b1098")]

 public partial class atc : usercontrol

 {

    initializecomponent();

 }

 5. 开发iobjectsafety接口

 

     为了让activex控件获得客户端的信任,用户控件必须实现`iobjectsafety`接口,并且下面的代码是固定的(guid也不能变)

 

复制代码

[comimport, guid("cb5bdc81-93c1-11cf-8f20-00805f2cd064")]

[interfacetype(cominterfacetype.interfaceisiunknown)]

public interface iobjectsafety

{

  [preservesig]

    int getinterfacesafetyoptions(ref guid riid, [marshalas(unmanagedtype.u4)] ref int pdwsupportedoptions, [marshalas(unmanagedtype.u4)] ref int pdwenabledoptions);

  

    [preservesig()]

    int setinterfacesafetyoptions(ref guid riid, [marshalas(unmanagedtype.u4)] int dwoptionsetmask, [marshalas(unmanagedtype.u4)] int dwenabledoptions);

}

复制代码

6. 用户控件实现iobjectsafety接口

 

复制代码

[guid("4d39585b-7947-4197-8bdb-b0a6918b1098")]

 public partial class atc : usercontrol, iobjectsafety

 {

    initializecomponent();

 }

 

 #region iobjectsafety 成员

 

 private const string _iid_idispatch = "{00020400-0000-0000-c000-000000000046}";

 private const string _iid_idispatchex = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";

 private const string _iid_ipersiststorage = "{0000010a-0000-0000-c000-000000000046}";

 private const string _iid_ipersiststream = "{00000109-0000-0000-c000-000000000046}";

 private const string _iid_ipersistpropertybag = "{37d84f60-42cb-11ce-8135-00aa004bb851}";

 

 private const int interfacesafe_for_untrusted_caller = 0x00000001;

 private const int interfacesafe_for_untrusted_data = 0x00000002;

 private const int s_ok = 0;

 private const int e_fail = unchecked((int)0x80004005);

 private const int e_nointerface = unchecked((int)0x80004002);

 

 private bool _fsafeforscripting = true;

 private bool _fsafeforinitializing = true;

 

 

 public int getinterfacesafetyoptions(ref guid riid, ref int pdwsupportedoptions, ref int pdwenabledoptions)

 {

     int rslt = e_fail;

 

    string strguid = riid.tostring("b");

    pdwsupportedoptions = interfacesafe_for_untrusted_caller | interfacesafe_for_untrusted_data;

    switch (strguid)

    {

        case _iid_idispatch:

        case _iid_idispatchex:

            rslt = s_ok;

            pdwenabledoptions = 0;

            if (_fsafeforscripting == true)

                pdwenabledoptions = interfacesafe_for_untrusted_caller;

            break;

        case _iid_ipersiststorage:

        case _iid_ipersiststream:

        case _iid_ipersistpropertybag:

            rslt = s_ok;

            pdwenabledoptions = 0;

            if (_fsafeforinitializing == true)

               pdwenabledoptions = interfacesafe_for_untrusted_data;

            break;

        default:

             rslt = e_nointerface;

            break;

    }

 

    return rslt;

 }

 

 public int setinterfacesafetyoptions(ref guid riid, int dwoptionsetmask, int dwenabledoptions)

 {

    int rslt = e_fail;

 

    string strguid = riid.tostring("b");

    switch (strguid)

    {

        case _iid_idispatch:

        case _iid_idispatchex:

            if (((dwenabledoptions & dwoptionsetmask) == interfacesafe_for_untrusted_caller) &&

                   (_fsafeforscripting == true))

                rslt = s_ok;

            break;

        case _iid_ipersiststorage:

        case _iid_ipersiststream:

        case _iid_ipersistpropertybag:

            if (((dwenabledoptions & dwoptionsetmask) == interfacesafe_for_untrusted_data) &&

                    (_fsafeforinitializing == true))

                rslt = s_ok;

            break;

        default:

            rslt = e_nointerface;

            break;

    }

 

    return rslt;

 }

 

 #endregion

复制代码

7. 获取activex的classid

 

  7.1. 打开vs2010->工具->oleview(若没有就自行添加,程序路径:c:\program files\microsoft sdks\windows\v7.0a\bin\oleview.exe)。

  7.2. 在`object classes`->`grouped by component category`->`.net category`找到刚才新建的activex控件

  7.3. 右键复制html标签

 

  

 

 

8. 页面引用activex控件

 

    在html页面上

 

<object classid="clsid:activex控件的clsid" codebase="控件打包后的exe文件名或cab文件名" width="200px" height="200px">

</object>