C# 在 vs2010 上开发 ActiveX 控件 【千辛万苦啊~】
由于B/S项目中需要使用到读卡器的功能,但是由于厂家只有提供一个 读卡的dll,那么怎样能在客户端使用读卡器呢,那么进过一番查找,最总决定使用ActiveX 控件来做。由于是第一次接触到 ActiveX 控件,所以再次过程中也是经历了千辛万苦,无数次的绝望,无数次的想放弃,不过最终还是查阅无数资料和无数次的尝试修改,总算是搞定了这一个项目!
本来我是打算用 vs2013 来做的,但是各种尝试都没有成功,主要是因为从vs2012 开始,微软没有用自家的安装部署功能了,而是用了别家的工具(详细了解可以去百度一下) 。 最后还是妥协了,特别下载了vs2010 来做。
这是vs2010 安装部署的界面
这是 vs2013 的安装部署界面
Oh~ yeah~
接下来把详细的过程写出来:
网上倒是有不少的例子,但是都不是最完整的,照着任何一个做都没有成功,最后结合了一下,才做了出来~
1. 已管理员身份运行 vs2010, 创建windows 窗体控件库,删除已有的 UserControl1.cs 控件,然后添加一个新的用户控件
2. 右键--项目属性:
应用程序 -- 程序集信息--:勾选 使程序集COM可见
生成:勾选为COM互操作注册
3. 修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]项(需要引用System.Security名称空间):
4. 为控件类添加GUID,这个编号将用于B/S系统的客户端调用时使用(可以使用 工具-创建GUID 菜单创建一个GUID,再复制):
5. 为了让ActiveX控件获得客户端的信任,控件类还需要实现一个名为“IObjectSafety”的接口,要创建该接口(注意,不能修改该接口的GUID值),IObjectSafety.cs代码如下:
1 namespace CardControl_01 2 { 3 [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] 4 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 5 public interface IObjectSafety 6 { 7 [PreserveSig] 8 void GetInterfacceSafyOptions( 9 int riid, 10 out int pdwSupportedOptions, 11 out int pdwEnabledOptions); 12 13 [PreserveSig] 14 void SetInterfaceSafetyOptions( 15 int riid, 16 int dwOptionsSetMask, 17 int dwEnabledOptions); 18 19 } 20 }
6.然后在控件类中继承并实现该接口,可以直接复制不用作任何更改:
namespace CardControl_01 { //使用生成的 GUID [GuidAttribute("8C680F71-C52F-494E-BD0F-A860B17B1D94")] public partial class CardControl : UserControl, IObjectSafety { public CardControl() { InitializeComponent(); } #region IObjectSafety 成员 public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions) { pdwSupportedOptions = 1; pdwEnabledOptions = 2; } public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions) { throw new NotImplementedException(); } #endregion #region 读卡处理操作逻辑 [SecuritySafeCritical] private void btnRead_Click(object sender, EventArgs e) { string data = new MJReadCard.CardManager().Read(); if (data.Equals("-1")) { lbStatus.Text = "状态:读数据失败!"; } else { txtShow.Text = data; lbStatus.Text = "状态:读数据成功!"; } } [SecuritySafeCritical] public string Read() { return new MJReadCard.CardManager().Read(); } [SecuritySafeCritical] private void btnWrite_Click(object sender, EventArgs e) { string data = txtShow.Text.Trim(); bool res = new MJReadCard.CardManager().Write(data); if (!res) { lbStatus.Text = "写数据失败"; } else { lbStatus.Text = "写数据成功"; } } [SecuritySafeCritical] public bool Write(string data) { return new MJReadCard.CardManager().Write(data); } #endregion } }
7. 开始打包发布:
(1). 添加新的项目
(2). 添加项目输出,还有就是添加文件,相关引用到的 dll
8. 最后生成项目后, 会在Debug文件夹下面生成 setup.exe 文件和一个 .msi 文件,我们项目中需要使用到的就是 setup.exe
9. 创建网站测试项目
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <title></title> 6 </head> 7 <body> 8 <!--读卡器--> 9 <object id="ActiveX" classid="clsid:8C680F71-C52F-494E-BD0F-A860B17B1D94" codebase="/AcitveXF/setup.exe" style=""></object> 10 11 <input id="btn" type="button" value="Read" /> 12 13 <script type="text/javascript"> 14 15 var btn = document.getElementById("btn"); 16 btn.onclick=function(){ 17 var cardID = ActiveX.Read(); 18 alert(cardID); 19 } 20 </script> 21 22 </body> 23 </html>
最终效果如下:
后续还有一些打包签名之类的操作,那么就再去网上找找....有很多的~