这几天Web项目中需要用到ActiveX插件(PS:听说这个是好久好久的东西了。。。),由于项目中需要调用本地资源所以只能研究研究这位老兄了。
先说说自己学习他的经历,开始的时候是用百度引擎检索自己所需要的数据,但是明显没有收获啊。只能FQ出去用Google了,Google真的很厉害,也希望大家都要习惯使用百度。在百度中找到了几篇比较详细的博客文章,按照他们的思路走了一遍虽然可以打包成*.cab文件但是无论是签名还是显示都会或多或少有那么一些不足。紧接着又是一天的各种Google呀。研究了近3天终于有个模样出来了。为了防止自己忘记再者为了和有需要的网友分享一下自己的心得,如有错误的地方请大家在下方指点出来以免误导其他人。
思路:
1、自定义一个【用户控件】
2、打包发布成【*.msi】文件
3、利用【cabarc.exe】工具把【*.msi】文件【*.inf】文件打包成【*.cab】文件
图文笔记开始:
1、新建一个【Windows窗体控件库】项目
2、编写自己的控件功能,本控件只实现一个弹窗
3、新建一个名为【IObjectSafety】的接口、注:接口内容下文将给出、不用修改任何代码!!!
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace EasyActivex { [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] [InterfaceTypeAttribute(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); } }
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 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 = ; if (_fSafeForScripting == true) pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; break; case _IID_IPersistStorage: case _IID_IPersistStream: case _IID_IPersistPropertyBag: Rslt = S_OK; pdwEnabledOptions = ; 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】文件
n Setup1.cab install.inf Setup1.msi ping -n 127.0.0.1 >nul
14、4个文件都准备好后双击批处理文件将生成【*.cab】文件,到此C#开发ActiveX已经完成
后续将介绍如何签名。话说我不知道怎么挂文件啊。。。用到的工具大家自行下载吧。。。