• c#封装ActiveX接口实践分析


           ActiveX接口 是一个开放的集成平台,为开发人员、用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内容的方法。 使用 ActiveX, 可轻松方便的在 Web页中插入 多媒体效果、 交互式对象、以及复杂程序,创建用户体验相当的高质量多媒体 CD-ROM

          简单的说,用activeX和js差不多,但是有些是js无法实现的,这个时候就可以考虑一下activeX,一般要求是在客户端执行的程序,比如对本机的串口操作等,而服务器端不用做任何的操作和加载任何的插件,下面来简单介绍下如何用C#自己封装一个activeX组件,并在web中应用。

        说明:我的这个例子是在实际工作中,需要把第三方厂家的C/S端动态库,封装为B/S端动态库。如果您的动态库不调用第三方厂家的动态库,可以在接口中去除链接即可。

        开发工具:VisualStudio2012 (VisualStudio2017在添加用户控件后,自动生成匹配的程序代码集,故不推荐!)

       步骤一:搭建开发环境

               说明:选择类库,编辑好名称和路径位置。

       

     步骤二: 更改“项目属性-应用程序-程序集信息”设置,勾选“使程序集 COM 可见

               说明:勾选COM有2处,都需要勾选

              第一处:

               

             第二处:

              

        步骤三: 修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]项(需要引用System.Security名称空间)

             

       

         步骤三: 添加一个Windows用户控件

            

            

     步骤四:防止浏览器一直弹出安全警告

          为了提高程序的安全性,以便在客户端安装的时候在浏览器提高信任度,我们需要实现接口IObjectSafety    

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Runtime.InteropServices;
     5 
     6 namespace mProjectName
     7 {
     8     [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
     9     [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    10     public interface IObjectSafety
    11     {
    12         [PreserveSig]
    13         int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
    14 
    15         [PreserveSig()]
    16         int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    17     }
    18 }
    IObjectSafety

         该类只是一个接口而已,我们还需要在自己的接口中去实现具体的方法。具体放置位置如下

         提示:这部分代码都是通用的,不必做任何修改。

         

     步骤五:用户控件的编写

       

        首先,用户控件的设计部分:XXX.Designer.cs的模块,最好需要弄点图片或者文字加载到上面去,一边用浏览器加载的时候方便判断是否加载成功。

       其次,编写主接口模块:

       

        首先,第一个接口  ItfLyCnIcObject是用来给家口注册后,提供函数名称的,您可以用这个函数实现不懂的功能,当然接口的函数还没有实现的,是在下面的XXX_BObject 接口里面实现的。

           ItfLyCnIcObject接口代码示例:

       

         主体XXXIc_Object接口代码示例:

         

        主体XXXIc_Object接口代码分为3部分,函数定义是为了加载第三方厂家的接口路径和方法,以及参数等,IObjectSafety接口是通用的,实现之前的IObjectSafety接口方法的具体实现,下面的具体方法是实现 ItfLyCnIcObject接口中方法的具体实现

        

           IObjectSafety接口方法是公用的,无需修改:

     1         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
     2         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
     3         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
     4         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
     5         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
     6 
     7         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
     8         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
     9         private const int S_OK = 0;
    10         private const int E_FAIL = unchecked((int)0x80004005);
    11         private const int E_NOINTERFACE = unchecked((int)0x80004002);
    12 
    13         private bool _fSafeForScripting = true;
    14         private bool _fSafeForInitializing = true;
    15 
    16 
    17         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
    18         {
    19             int Rslt = E_FAIL;
    20 
    21             string strGUID = riid.ToString("B");
    22             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
    23             switch (strGUID)
    24             {
    25                 case _IID_IDispatch:
    26                 case _IID_IDispatchEx:
    27                     Rslt = S_OK;
    28                     pdwEnabledOptions = 0;
    29                     if (_fSafeForScripting == true)
    30                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
    31                     break;
    32                 case _IID_IPersistStorage:
    33                 case _IID_IPersistStream:
    34                 case _IID_IPersistPropertyBag:
    35                     Rslt = S_OK;
    36                     pdwEnabledOptions = 0;
    37                     if (_fSafeForInitializing == true)
    38                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
    39                     break;
    40                 default:
    41                     Rslt = E_NOINTERFACE;
    42                     break;
    43             }
    44 
    45             return Rslt;
    46         }
    47 
    48         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
    49         {
    50             int Rslt = E_FAIL;
    51 
    52             string strGUID = riid.ToString("B");
    53             switch (strGUID)
    54             {
    55                 case _IID_IDispatch:
    56                 case _IID_IDispatchEx:
    57                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
    58                             (_fSafeForScripting == true))
    59                         Rslt = S_OK;
    60                     break;
    61                 case _IID_IPersistStorage:
    62                 case _IID_IPersistStream:
    63                 case _IID_IPersistPropertyBag:
    64                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
    65                             (_fSafeForInitializing == true))
    66                         Rslt = S_OK;
    67                     break;
    68                 default:
    69                     Rslt = E_NOINTERFACE;
    70                     break;
    71             }
    72 
    73             return Rslt;
    74         }
    IObjectSafety接口具体实现

           ItfLyCnIcObject中的方法实现中的方法名称和具体参数,以及个数都必须一致

                

            之后,再从新生成无误后,会在bin文件的Debug文件中生成你封装好的dll

                 

     步骤六:注册该接口

             这个得到的dll要和第三方厂家的dll放到一起(就是我们之前图片中的哪个第三方厂家的DLL),一并放到C:WindowsSYSWOW64目录下,因为我的是windows64位电脑,如果你的电脑是32位的,一般放置到C:WindowsSystem32目录下。

           之后打开CMD,写入一下注册字符:

          "C:WindowsMicrosoft.NETFrameworkv2.0.50727RegAsm.exe" /codebase C:WindowsSysWOW64XXXXc_B.dll

          具体截图如下:

           

        然后回车即可注册成功。(中间可能有警告,不用管,只要有注册成功字样即可)

     步骤七:接口的唯一ClassID查看

                  这个ClassID就是浏览器识别该该接口的唯一凭证,也就是说有了这个ClassID,一台电脑原则上可以注册无数的这种接口。可以通过接口查看器查看

                  我用的查看工具是oleview,大家可以用其他的看看,一般只要是正确的注册,都可以看到接口名称,如果没有看到,怎么能够接口没有注册成功。

                  

          步骤八:调用接口

         新建一个html页面,添加下面的代码

        

         具体代码分析:

         

             到此,就基本上结束了,页面可以用JS来调用了,另外,浏览器的安全设置大家最好按网上其他大神说的那样设置就好。

             由于这个是实际项目中的上线代码,故,内容可以不能全部公开,部分关键字段也做了刷白处理,可能对您观看造成不便,请多多包涵。如果大家有兴趣或者疑问,欢迎大家把疑问发送到我的邮箱1732182169@qq.com,或者直接QQ:1732182169联系我,大家一起学习探讨!

    另外可以参考下面这位大神写的,也很不错:http://www.cnblogs.com/shuang121/archive/2012/06/04/2534296.html

  • 相关阅读:
    使用 apache ant 轻松实现文件压缩/解压缩(转)
    Ajax下载文件(页面无刷新)
    java实现写大量数据到文件中
    mysql的wait_timeout配置(此处处理方法是有问题的,不建议作为操作参考)
    Class对象
    使用Comparable接口的小例子
    java打印菱形的简单方法
    自适应学习率调整:AdaDelta
    神经网络模型算法与生物神经网络的最新联系
    [杂谈]机器学习:数学、概率与人工智能
  • 原文地址:https://www.cnblogs.com/xiaobaicai12138/p/7717773.html
Copyright © 2020-2023  润新知