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进行硬件设备操作的朋友一些帮助。

silverlight 进行本地串口调用的一种可行的解决方法的更多相关文章

  1. silverlight 进行本地串口调用的一种可行的解决方法 之silverlight端代码

    接上边的文章. 在javascript暴露操作activex 串口接收之后,就是silverlight端进行串口数据的显示,我们的显示方式比较简单,只是为了演示,我们每隔1秒进行数据的获取并显示, 为 ...

  2. 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法

    <对“XXX::Invoke”类型的已垃圾回收委托进行了回调.这可能会导致应用程序崩溃.损坏和数据丢失.向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们& ...

  3. 调用MediaScannerConnection 发生内存泄露的解决方法

    调用MediaScannerConnection发起扫描时经常会发生内存泄露,例如: E ActivityThread: Activity FolderListActivity has leaked ...

  4. Ubuntu几种常见乱码解决方法

    一.网页中的flash乱码:        ubuntu默认浏览器是Firefox,但是Ubuntu默认不安装像flash这种带版权的软件,所以当你浏览像youku或网页播放器时,这种带有 flash ...

  5. EasyPlayer RTSP播放器OCX RegSvr32注册报错,DllRegisterServer调用失败,错误代码为0x80040200 解决方法

    问题描述 模块"EasyPlayer-RTSPWebActiveX.ocx" 已加载,但对DLLRegisterServer调用失败,错误代码为0x80040200. 解决方法 是 ...

  6. Dedecms本地上传缩略图无法自动添加水印的解决方法

    客户遇到一个问题,DEDECMS(V5.7)后台添加文档时,本地上传缩略图无法自动添加水印(系统设置里的图片水印设置没有问题),找了半天,终于找到了解决方法,留个记号: 打开dede/archives ...

  7. 用链表和数组实现HASH表,几种碰撞冲突解决方法

    Hash算法中要解决一个碰撞冲突的办法,后文中描述了几种解决方法.下面代码中用的是链式地址法,就是用链表和数组实现HASH表. he/*hash table max size*/ #define HA ...

  8. (转)maven怎么 引入(或引用/使用) 自定义(或本地/第三方) jar的三种方式 图文教程 方法二最简单

    转:https://blog.csdn.net/wabiaozia/article/details/52798194 准备工作: 假如我有一个自定义jar是:123456.jar,下载地址http:/ ...

  9. 调用Excel.Application报错的解决方法

    之前由于装了WPS后,VBA和python调用某些OFFICE的端口一直报错.网上找了无数的解决办法.也没有解决. 将注册表清理.不行. 将WPS卸载.不行. 将office重装.不行. 之后找到了个 ...

随机推荐

  1. memcached set命令的大致处理逻辑笔记

    这次记录状态机的主要逻辑,跟踪set命令的执行流程,暂不涉及到内存申请这一块,下面内容基本都是代码注释 首先还是补充了解下客户连接在发送数据到数据被处理并返回过程中conn的各种状态的表示 enum ...

  2. php--------合并2个数字键数组的值

    开发中遇到了,数组合并并去除重复这个功能,查阅资料, 找到了一个方法,分享一下. <?php /** * PHP合并2个数字键数组的值 * * @param array $arr1 * @par ...

  3. python-day34--并发编程之多线程

    理论部分 一.什么是线程: 1.线程:一条流水线的工作过程  2.一个进程里至少有一个线程,这个线程叫主线程 进程里真正干活的就是线程 3.进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资 ...

  4. seekg()/seekp()与tellg()/tellp()的用法详解

    本文转载于:http://blog.csdn.net/mafuli007/article/details/7314917 (在tcp的文件发送部分有应用) 对输入流操作:seekg()与tellg() ...

  5. OAF 供应商门户添加功能标签后获取当前供应商VendorId的方法

    一种是参考管理页面 /oracle/apps/pos/supplier/webui/SuppDtPG 在目标页面的AM中添加VO实例,oracle.apps.pos.supplier.server.S ...

  6. 区别@ControllerAdvice 和@RestControllerAdvice

    @ControllerAdvice和@RestControllerAdvice都可以指向控制器的一个子集: // 指向所有带有注解@RestController的控制器 @ControllerAdvi ...

  7. Inno Setup 编译器操作

    Inno Setup 编译器 1◆ 下载inno ha_innosetup5502_skygz_DownG.com 2◆ 安装 next 3◆ 操作 success 4◆ 测试安装 5◆ 卸载 uni ...

  8. SQL Server 自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...

  9. Hexo博客搭建教程

    1.使用淘宝npm源 $ npm install -g cnpm --registry=https://registry.npm.taobao.org 2.安装hexo cnpm install -g ...

  10. Python 数据类型--字典类型

    字典 dict 字典是Python的另一种有序的可变数据结构,且可存储任意类型对象. 字典是一种键值对的数据容器,每个键值(key:value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典 ...