zoukankan      html  css  js  c++  java
  • 【CSharp】C#开发ActiveX插件

        这几天Web项目中需要用到ActiveX插件(PS:听说这个是好久好久的东西了。。。),由于项目中需要调用本地资源所以只能研究研究这位老兄了。

        先说说自己学习他的经历,开始的时候是用百度引擎检索自己所需要的数据,但是明显没有收获啊。只能翻墙出去用Google了,Google真的很厉害,也希望大家都要习惯使用百度。在百度中找到了几篇比较详细的博客文章,按照他们的思路走了一遍虽然可以打包成*.cab文件但是无论是签名还是显示都会或多或少有那么一些不足。紧接着又是一天的各种Google呀。研究了近3天终于有个模样出来了。为了防止自己忘记再者为了和有需要的网友分享一下自己的心得,如有错误的地方请大家在下方指点出来以免误导其他人。

      思路:

      1、自定义一个【用户控件】

      2、打包发布成【*.msi】文件

      3、利用【cabarc.exe】工具把【*.msi】文件【*.inf】文件打包成【*.cab】文件

      图文笔记开始:

      1、新建一个【Windows窗体控件库】项目

      2、编写自己的控件功能,本控件只实现一个弹窗

      3、新建一个名为【IObjectSafety】的接口、注:接口内容下文将给出、不用修改任何代码!!!

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

      4、自定义控件类继承并实现【IObjectSafety】接口、注:实现【IObjectSafety】接口部分下文将给出、不用修改任何代码

     #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

      5、给自定义控件类设置一个【GUID标签】,注:此【GUID】值为页面中【OBJECT】标签所引用的【classid】

      需要引入命名控件

    using System.Runtime.InteropServices;
    [Guid("A212CB6C-F833-454C-9CD2-C38A36386DE3")]

      提示:GUID可以用【VS2010】环境任务栏中【工具】菜单下的【新建GUID】生成,如下图

      6、在项目结构中打开【Properties】文件夹中的【AssemblyInfo】写入下面这句话

    [assembly: AllowPartiallyTrustedCallers()]

      7、【项目】点击右键打开【属性窗口】打开【程序集信息】勾选【使程序集COM可见】

      8、左侧点击【生成】选项卡勾选【为COM互操作注册】、左上角【配置】切换为【Release】勾选下方【为COM互操作注册】,保存关闭【属性】窗口

      9、以上则完成了ActiveX功能的开发、下面新建【安装项目】给【*.dll】文件发布成【*.msi】文件

      10、在引进来的【*.dll】文件单击右键【属性】修改【Register】为【vsdraCOM】

      11、把用户自定义控件的【dll】添加到【安装项目】并重新生成【安装项目】则会生成一个【*.msi】文件,到此功能开发与发布完成

      12、下面将进行【*.msi】文件打包成【*.cab】文件、首先准备工作是下载【cabarc.exe】工具、新建一个【*.inf】配置文件下文将给出

    [version]  
    signature="$CHICAGO$"  
    AdvancedINF=2.0  
    
    [Setup Hooks]  
    hook1=hook1  
    
    [hook1]  
    run=msiexec.exe /i "%EXTRACT_DIR%Setup1.msi" /qn

      13、用批处理文件生成【*.cab】文件

    "cabarc.exe" -s 6144 n Setup1.cab install.inf Setup1.msi
    ping -n 20 127.0.0.1 >nul

      14、4个文件都准备好后双击批处理文件将生成【*.cab】文件,到此C#开发ActiveX已经完成

      后续将介绍如何签名。话说我不知道怎么挂文件啊。。。用到的工具大家自行下载吧。。。

  • 相关阅读:
    汉诺塔问题
    两个有序链表序列的合并
    数列求和
    求集合数据的均方差
    [NOIP2014] 提高组 洛谷P1328 生活大爆炸版石头剪刀布
    [NOIP2014] 普及组
    洛谷P1726 上白泽慧音
    洛谷P1808 单词分类
    洛谷P1889 士兵站队
    洛谷P1288 取数游戏II
  • 原文地址:https://www.cnblogs.com/MangoCai/p/4097528.html
Copyright © 2011-2022 走看看