silverlight 是一个很不错的开发平台,我们可以设计出很绚丽的界面,用户可以拥有很好的体验,但是就目前来说,进行本地串口的直接调用时不行的,因为安全的原因,有没有相对简单的调用方式呢? 答案是有的,
大家应该还记得在B/S 架构中我们使用的activex 插件吧,这是可以进行本地调用的一种方式,但是有一定的局限性,就是只能在IE浏览器中,也就是使用windows平台,今天我的解决方法也是使用activex插件,对于跨平台当然是目前比较难办的。
具体的思路如下:
在上面的一般关于silverlight 托管代码与javascript 互调用的文章中有介绍,今天的设计就是依托那篇文章。我使用activex 插件然后使用javascript调用activex插件中的串口的操作方法,使用silverlight中托管代码与javascript的互调用,直接就可以使用silverlight操作串口了,当然是比较简单的,只是使用activex插件作为一个中间的桥梁而已。
以下就是实现的细节
1,当然就是进行activex插件的制作了,我是.net 技术的热爱者,当然是使用.net 进行activex插件的开发,这个是比较简单的,只是中间有一些细节需要注意。
我的操作比较简单就是打开串口,关闭串口 。
/// 进行activex 安全的接口定义
[ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IObjectSafety { [PreserveSig] void GetInterfacceSafyOptions( int riid, out int pdwSupportedOptions, out int pdwEnabledOptions); [PreserveSig] void SetInterfaceSafetyOptions( int riid, int dwOptionsSetMask, int dwEnabledOptions); } [Guid("2ed4b7c5-09e8-483f-9566-8895afefba88")] public partial class UserControl1 : UserControl, IObjectSafety { public UserControl1() { InitializeComponent(); } public string demo() { return "dalong"; } /// <summary> /// 打开指定的串口 /// </summary> /// <param name="ComName"></param> /// <returns>返回操作的状态</returns> public bool Start(string ComName) { bool isopen = false; System.IO.Ports.SerialPort port = new SerialPort(ComName); if (port.IsOpen) { isopen = true; } else { try { port.Open(); isopen = true; } catch (Exception) { } } return isopen; } /// <summary> /// 关闭指定的串口 /// </summary> /// <param name="ComName"></param> /// <returns>返回操作的状态</returns> public bool Stop(string ComName) { bool isclose = false; System.IO.Ports.SerialPort port = new SerialPort(ComName); if (port.IsOpen) { try { port.Close(); isclose = true; } catch (Exception) { isclose = false; } } return isclose; } 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(); } }这就是activex 的方法,一个重要的东西就是进行.net 控件的COM暴露。只是进行设置就行。
如下:
using System.Reflection;
using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Security;// 有关程序集的常规信息通过以下// 特性集控制。更改这些特性值可修改// 与程序集关联的信息。[assembly: AssemblyTitle("Dalong")][assembly: AssemblyDescription("")][assembly: AssemblyConfiguration("")][assembly: AssemblyCompany("")][assembly: AssemblyProduct("Dalong")][assembly: AssemblyCopyright("Copyright © 2013")][assembly:AllowPartiallyTrustedCallers()][assembly: AssemblyTrademark("")][assembly: AssemblyCulture("")]// 将 ComVisible 设置为 false 使此程序集中的类型// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,// 则将该类型上的 ComVisible 特性设置为 true。[assembly: ComVisible(true)]// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID// 程序集的版本信息由下面四个值组成://// 主版本// 次版本 // 内部版本号// 修订号//// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,// 方法是按如下所示使用“*”:// [assembly: AssemblyVersion("1.0.*")][assembly: AssemblyVersion("1.0.0.0")][assembly: AssemblyFileVersion("1.0.0.0")]2,就是操作的方法了。使用silverlight互操作的技术。
这是使用activex插件的代码:
<object id="Control" classid="clsid:2ed4b7c5-09e8-483f-9566-8895afefba88" width="0px" height="0px"></object>
classid 就是你创建的插件的GUID 这个是根据你创建生成的。具体的可以网上搜索相关文章。
function Satrt(comName) {
return Control.Start(comName); } function Stop(comName){ return Control.Stop(comName); }这两个javascript代码是将要暴露给silverlight进行调用的串口操作代码。比较简单。
public bool Start(string comName)
{ HtmlWindow win = HtmlPage.Window; // 获取客户端的javascript方法 ScriptObject sObj = win.GetProperty("Satrt") as ScriptObject; // 执行方法 bool result = (bool)sObj.InvokeSelf(comName); return result; } public bool Stop(string comName) { HtmlWindow win = HtmlPage.Window; // 获取客户端的javascript方法 ScriptObject sObj = win.GetProperty("Stop") as ScriptObject; // 执行方法 bool result = (bool)sObj.InvokeSelf(comName); return result; }这两个是进行silverlight调用的方法,比较简单吧,上面的width="0px" height="0px" 主要是不让客户端看到activex插件。虽然说有点曲折,但是这种实现方式还是可以解决silverlight无法直接进行串口操作的难题,希望对于使用silverlight进行硬件设备操作的朋友一些帮助。