一个电脑建设多个网站,怎么找到做网站的客户,黄岛网站建设服务公司,哈尔滨h5建站模板前言 ActiveX控件以前也叫做OLE控件#xff0c;它是微软IE支持的一种软件组件或对象#xff0c;可以将其插入到Web页面中#xff0c;实现在浏览器端执行动态程序功能#xff0c;以增强浏览器端的动态处理能力。通常ActiveX控件都是用C或VB语言开发#xff0c;本文介绍另一… 前言 ActiveX控件以前也叫做OLE控件它是微软IE支持的一种软件组件或对象可以将其插入到Web页面中实现在浏览器端执行动态程序功能以增强浏览器端的动态处理能力。通常ActiveX控件都是用C或VB语言开发本文介绍另一种方式在.NET Framework平台上使用C#语言开发ActiveX控件。 虽然本文通篇都在讲如何使用C#语言开发ActiveX控件但我并不极力推荐使用这种技术因为该技术存在明显的局限即需要浏览器端安装.NET Framework版本取决于开发ActiveX控件使用的.NET Framework版本该局限对于挑剔的互联网用户几乎是不可接受的。所以我建议以下几条均满足时方可考虑使用该技术 开发团队中没有人掌握使用C/VB开发ActiveX控件技术该ActiveX控件不用于互联网用户对仅能使用IE浏览器访问表示可以接受用户对在浏览器端安装.NET Framework组件表示可以接受。另外我建议如果不是因为控件的依赖库基于更高版本的.NET Framework或需要更高版本的.NET Framework提供的扩展功能如需要WCF等尽量在.NET Framework 2.0上开发ActiveX控件因为.NET Framework 2.0只有20M相比300M的.NET Framework 3.5和40M的.NET Framework 4.0都要小很多对客户端操作系统的要求也要低很多并且随着Windows版本的不断升级换代Windows Vista以后的版本已经内置了.NET Framework 2.0。等到Windows XP系统寿终正寝之时也将迎来该技术的春天。所以别被我上面的建议夯退了掌握该技术其实还是蛮有实用价值的毕竟C#高效的开发效率很有吸引力。 本文接下来将使用C#语言开发一个ActiveX控件实现对浏览器端的MAC地址遍历功能另外提供一个在Web静态页面中调用该控件的测试实例。本实例的开发环境为Visual Studio 2010旗舰版SP1目标框架为.NET Framework 2.0浏览器端测试环境为Windows 7旗舰版IE8。 控件开发 使用C#进行ActiveX控件开发过程其实很简单。首先在解决方案中添加一个类库项目目标框架使用.NET Framework 2.0如图1所示 图1创建ActiveX控件类库 此处有一个关键操作需要设置类库项目属性-程序集信息-使程序集COM可见如图2所示 图2设置ActiveX控件类库程序集COM可见 ActiveX类库的内容大致包括两部分IObjectSafety接口和实现该接口的控件类。考虑所有控件类都要实现IObjectSafety接口可以将该接口的实现抽象为一个控件基类。 一、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);
} 二、ActiveXControl控件基类 public abstract class ActiveXControl : 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
} 三、MacActiveX控件类 [Guid(65D8E97F-D3E2-462A-B389-241D7C38C518)]
public class MacActiveX : ActiveXControl
{public string GetMacAddress(){var mc new ManagementClass(Win32_NetworkAdapterConfiguration);var mos mc.GetInstances();var sb new StringBuilder();foreach (ManagementObject mo in mos){var macAddress mo[MacAddress];if (macAddress ! null)sb.AppendLine(macAddress.ToString());}return sb.ToString();}
} 注意第一行指定的Guid值即为该ActiveX控件的唯一标识请保证其唯一性。Guid的生成有多种方法你可以在系统目录的Program Files目录搜索一个名为guidgen.exe的工具用该工具产生也可以写一段测试代码调用Guid.NewGuid()方法产生有的Visual Studio版本也提供了快捷方式在“工具-生成GUID”菜单下。另外访问MAC需要添加对System.Management系统组件的引用。 到此控件类库的开发工作就做完了整个实现过程确实很简单。 发布 C#开发的ActiveX控件类库不像OCX那样可以直接通过regsvr32.exe注册实际上微软提供了替工具regasm.exe但由于这种方式要不能实现自动升级所以本文就不介绍了要使控件类库运行于浏览器端可以采取两种方式一种是将控件类库打包为MSI安装包然后直接在浏览器端安装另一种是将MSI再封装为一个CAB包这个CAB包就是一个ActiveX控件了可以将它随应用程序一并发布浏览器端访问包含有该控件的页面时就会自动提示安装了。接下来就后一种发布方式进行详细讲解。 一、安装项目 在解决方案中添加一个安装项目如图3所示 图3添加安装项目 右键点击新添加的安装项目依次选择“添加-项目输出”菜单打开添加项目输出组对话框并选择ActiveX控件类库“CSharpActiveX”作为主输出如图4所示 图4添加项目输出 双击安装项目检测到的依赖项“Microsoft .NET Framework”打开安装项目的启动条件界面选中“.NET Framework”项如图5所示 图5安装项目启动条件 按F4快捷键打开属性窗口设置.NET Framework项的Version为“.NET Framework 2.0”如图6所示 图6设置安装项目的依赖框架 下面这步很关键选中“主输出来自CSharpActiveX(活动)”项如图7所示 图7主输出内容项 设置主输出项内容的Register属性值为vsdrpCOM如图8所示 图8设置主输出项属性 二、制作CAB包 Visual Studio 2010提供了CAB项目模板但非常遗憾无论我怎么设置其生成的CAB安装包都不能在终端成功安装最终只能放弃转而选择了makecab.exe工具。源码提供了该打包工具位于CAB目录下共包含makecab.exe、cab.ddf、installer.inf和makecab.bat四个文件其中cab.ddf和installer.inf文件需要简单说明下。 cab.ddf文件定义了CAB文件的打包行为内容包括打包参数打包内容项以及输出文件等。需要指出的是使用C#开发的ActiveX控件CAB包中需要包含MSI文件和installer.inf安装文件两部分。cab.ddf文件内容如下 .OPTION EXPLICIT
.Set Cabineton
.Set Compresson
.Set MaxDiskSizeCDROM
.Set ReservePerCabinetSize6144
.Set DiskDirectoryTemplate.
.Set CompressionTypeMSZIP
.Set CompressionLevel7
.Set CompressionMemory21
.Set CabinetNameTemplateCSharpActiveX.CAB
installer.inf
CSharpActiveX.msi installer.inf文件定义了CAB文件的安装行为作为控件的一部分打入CAB包中其内容如下 [Setup Hooks]
hook1hook1[hook1]
runmsiexec /i %EXTRACT_DIR%\CSharpActiveX.msi /qn[Version]
Signature $CHICAGO$
AdvancedInf2.0 makecab.bat文件是调用makecab.exe进行打包的批处理文件内容如下 makecab.exe /f cab.ddf 当生成安装项目后将CSharpActiveX.msi文件拷贝到CAB目录下就可以双击makecab.exe文件进行打包了执行完成后会输出CSharpActiveX.CAB文件这就是所谓的ActiveX控件了。 三、签名 IE采用了AuthentiCode代码签名技术对浏览器端安装ActiveX控件行为进行了控制。上面生成的ActiveX控件如果想在浏览器端成功安装需要对浏览器进行设置具体操作参见部署章节。 让所有用户都对IE进行设置显得不太友好为此我们可以考虑使用AuthentiCode技术对ActiveX控件进行签名。Visual Studio 2010附带的signtool.exe以前版本的VS提供的是另一个工具signcode.exe代码签名工具可以完成该工作注意并非一定要用微软提供的工具进行签名只要按照AuthentiCode技术标准使用 PKCS#7标准定义的数据结构生成待签名文件的数字签名并加入到待签名文件的PE结构中即可。但需要先准备一个PKCS#12证书及私钥文件(.pfx)注意该证书的增强型密钥用法须包含代码签名这项如图9所示 图9代码签名证书 本文源码提供了一份测试PKCS#12文件Apollo.pfxPIN码为11111111。在Visual Studio命令提示(2010)中进入源码的CAB目录输入如下命令即可对ActiveX控件进行签名操作了 signtool sign –f Apollo.pfx –p 11111111 CSharpActiveX.CAB 图10对比了签名前后的ActiveX控件文件属性可以看出签名后的ActiveX控件属性中已经多了一项数字签名表示该文件已经过签名。 图10签名前后的ActiveX控件属性对比 出于方便考虑本文源码的CAB目录下提供了一份signtool.exe工具的拷贝这样就可以将签名命令加入makecab.bat文件中修改后的makecab.bat我将其命名为makecabsigned.bat内容如下 makecab.exe /f cab.ddf
signtool sign -f Apollo.pfx -p 11111111 CSharpActiveX.CAB 应用 ActiveX控件用于HTML静态页面执行于IE浏览器端。需要以object标签的形式引入页面文件然后使用Javascript语言调用它。测试代码如下 html
headtitleCSharpActiveX测试/title
/head
body
object idcSharpActiveX classidclsid:65D8E97F-D3E2-462A-B389-241D7C38C518 codebaseCSharpActiveX.CAB#version1,0,0 styledisplay: none;/objectscript typetext/javascript languagejavascript deferdefervar activeX document.getElementById(cSharpActiveX);alert(activeX.GetMacAddress());/script
/body
/html 注意object标签的classid属性值即为MacActiveX类的Guid特性值。 部署 ActiveX控件在IE浏览器端的部署会因ActiveX控件是否签名而有所区别。下面就以此分类进行说明。当然首先需要将test.htm和CSharpActiveX.CAB文件部署到服务器上假设部署后的访问地址为http://192.168.1.1/test.htm。 一、部署未签名的ActiveX控件 未签名的ActiveX控件不受浏览器端信任默认是不被允许安装的。需要先将站点添加为可信站点具体步骤为依次打开IE“工具-Internet选项”在“安全”选项卡中选中“可信站点”如图11所示 图11 Internet安全选项 点击“站点”按钮打开可信站点管理对话框将服务器站点添加到可信站点列表中如图12所示 图12可信站点对话框 回到“Internet选项”对话框点击“自定义级别”选项卡打开可信站点的安全设置对话框如图13所示 图13可信站点安全设置对话框 确认“对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本”项设置为“启用”“下载未签名的ActiveX控件”项设置为“提示”。 IE设置完成后访问http://192.168.1.1/test.htm测试页面注意Windows 7需要“以管理员身份运行”IE方可成功安装ActiveX控件IE便会提示加载ActiveX控件如图14所示 图14首次访问提示加载ActiveX控件 点击“为此计算机上的所有用户安装此加载项”IE将弹出安全警告确认是否要安装该ActiveX控件如图15所示 图15 ActiveX控件安装安全警告 点击“安装”按钮确认安装该ActiveX控件待IE状态栏进度条完成说明控件已安装完成可以通过查看“卸载或更改程序”项来确认是否安装成功如图16所示 图16确认ActiveX控件成功安装 我们可以从ActiveX控件安装过程看出浏览器端其实是以静默安装的方式完成对CAB包中的MSI安装文件的安装有点拗口J。安装完成后页面成功调用ActiveX控件弹出接口调用结果注意Windows 7需要重启IE且不能用“以管理员身份运行”方式启动否则会再次提示安装ActiveX控件但其实控件已经成功安装了这个问题很奇怪效果如图17所示 图17成功调用ActiveX控件接口 二、部署已签名的ActiveX控件 因为IE默认允许安装并运行收信任的已签名ActiveX控件所以通过对ActiveX控件签名可以有效简化浏览器端的配置工作。你仅需要安装签名所用的证书及其证书链文件本文源码提供的签名文件所含证书是自签名证书所以它的证书链就只是它自己。打开源码CAB目录下的Apollo.cer与Apollo.pfx文件对应的数字证书文件代码签名证书文件如图18所示 图18签名证书文件 点击“安装证书”按钮将该证书安装到“受信任的根证书颁发机构”如图19所示 图19安装代码签名证书 打开IE的“工具-Internet选项”对话框选择“内容”选项卡点击“证书”按钮打开IE证书对话框确认在“受信任的根证书颁发机构”选项卡中包含刚才导入的代码签名证书如图20所示 图20成功导入代码签名证书 此时再访问测试页面http://192.168.1.1/test.htmIE就会提示安装ActiveX控件了而不再需要将站点添加到可信站点并设置IE选项了。 但是如果用户不能接受初次安装需要导入代码签名证书及其证书链的方式怎么办呢从图20可以看到Windows其实默认内置了一些权威的CA机构证书可以向这些机构申请一份代码签名证书及私钥文件来对ActiveX控件签名这样就可以避免该问题了。但是向权威的CA机构申请证书是需要付费的所以需要权衡成本和易用性后再做出选择。 升级 要使C#编写的ActiveX控件支持自动升级需要做四件事情即升级ActiveX控件库版本、升级安装项目版本、设置安装项目注册表项版本和升级网页object版本。 一、升级ActiveX控件版本 打开ActiveX控件项目的“程序集信息”对话框升级程序集版本和文件版本如图21所示 图21升级ActiveX控件版本 二、升级安装项目版本 选中安装项目按F4快捷键打开安装项目的属性窗口升级安装项目的版本如图22所示 图22升级安装项目版本 注意此处还有一项关键工作要做就是设置RemovePreviousVersions属性值为True这样就会在升级时先自动卸载之前版本的控件。 三、设置安装项目注册表项版本 浏览器端检测ActiveX控件是否需要升级是通过比对object标签的codebase属性值和本地HKEY_CLASSES_ROOT/CLSID/{GUID}/InstalledVersion键值是否相等来判断的。所以如果要实现自动更新需要手动添加该注册表项并在每次升级控件时相应更改该项键值。 右键点击安装项目依次选择“视图-注册表”菜单打开安装项目的注册表编辑界面并在HKEY_CLASSES_ROOT节点下建立CLSID/{GUID}/InstalledVersion注册表键路径如图23所示 图23创建注册表键路径 右键点击InstalledVersion键节点选择“新建-字符串值”菜单新建一个名称为空空名称会显示为“(默认值)”值为当前控件版本号的键值如图24所示 图24添加InstalledVersion默认键值 该步骤有几个地方需要特别说明。首先{GUID}指的是ActiveX控件类的GUID对应本文MacActiveX类指定的GUID且该项需要包括左右花括号其次如果该安装项目用于发布多个ActiveX控件类需要创建多个{GUID}/InstalledVersion路径最后InstalledVersion的默认键值的主次版本号间是用“,”分隔而不是“.”后续升级时需要同步升级该键值版本号。 四、升级网页object版本 最后需要升级网页中的ActiveX对象引用版本号如下用下划线标识部分 object idcsharpActiveX classidclsid:65D8E97F-D3E2-462A-B389-241D7C38C518 codebaseCSharpActiveX.CAB#version1,0,1 styledisplay: none;/object 重新生成安装程序打CAB包将升级的页面及ActiveX控件CAB包更新到服务器。此时浏览器端重新访问时就会提示/自动升级ActiveX控件了。 总结 本文是《使用C#开发ActiveX控件》一文的升级版本从ActiveX控件的开发、发布、应用、部署和升级整个生命周期系统地介绍了使用C#开发ActiveX控件技术的方方面面对整个过程中可能遇到的一些技术难点进行了逐一讲解并对其中涉及的一些知识进行了简单介绍。希望本文能够解答自上一篇文章发布以来众多网友提出的种种问题帮助大家成功掌握这门技术。 文章转自使用C#开发ActiveX控件新 附件下载示例源码本文PDF版本 转载于:https://www.cnblogs.com/go-jzg/p/6444701.html