C# ActiveX开发及安装部署
2015-08-06 09:08
585 查看
最近项目中,因为需要在WEB页面上操作串口,包括串口查询、打开、发送指令、接收数据、关闭串口等功能。如下所示:
View Code
在使用JS调用ActiveX的时候碰上问题一:方法可以成功调用,而事件却调用失败。网上文章大都是说JS如何调ActiveX,而ActiveX这边的方法或者事件需要满足什么条件才能被JS成功调用却少有涉及。正当我山穷水尽疑无路的时候,事情有了转折,无意中看到一篇老外写的文章。链接地址是:http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step。才知道事件需要实现一个接口才能被JS识别。所以这部分代码后面被加上去了:
控件类名前面也加上这个
事件定义如下:
本地打开网页,执行全部功能,操作正常,大功告成!!!
随后我把网页在本地发布并使用局域网中其他电脑(操作系统WIN7)IE访问该网页。那么问题来了:
1:机器弹出对话框拒绝安装当前ActiveX。经过对IE internet选项设置,放开对无签名ActiveX访问限制后。有的机器能弹出安装对话框,有的机器仍然坚决禁止。而且就算是弹出安装对话框,在确认安装后,对话框消失,插件也没装上。。。
好吧,这个问题也是没搞明白啥原因。后面时间紧迫,只好给客户一个下载链接,自己去点击下载。
2:下载安装包并安装完毕后,在客户机器上操作网页功能。前面几个按钮功能都OK,但是在填入指令点击发送,网页出现崩溃重新刷新的情况,而且换了几台机器都是这样。后面想起在生成安装包的时候,有弹出一个对话框,提示Visual Studio registry capture utility 已停止工作。百度一番后,找到解决方法:在Microsoft Visual Studio 9.0/Common7/Tools/Deployment 路径下面的regcap.exe文件,点击右键在属性页面中,选择兼容性页面,选中“以兼容模式运行”框就好了。兼容win7 就行。
相应设置后,重新生成安装文件。。。在客户机上安装后,一切正常!!!
最后附上完整项目代码:http://pan.baidu.com/s/1hq8MzJ2
<html> <head> <title>JavaScript串口测试</title> <meta http-equiv="Content-Type" content="text/html; charset=GB2312" /> <script language="javascript" type="text/javascript"> <!-- function getComPorts() { var ports = webSerial.getComPorts(); var arr = ports.split(','); var ctl = document.getElementById("ComName"); if(ctl) { ctl.options.length = 0; for(var i=0;i<arr.length;i++) { ctl.options[i] = new Option(arr[i],arr[i]); } } } function connectComPort() { var com = document.getElementById("ComName").value.toString(); var baudRate = document.getElementById("BaudRate").value; var result = webSerial.connect(com,baudRate); alert(result); } function clearComPort() { webSerial.clear(); alert("清理串口成功!"); } function closeComPort() { webSerial.close(); alert("关闭串口成功!"); } function writeString() { var hexString = document.getElementById("txtSend").value.toString(); webSerial.writeString(hexString); alert("发送指令成功!"); } function clearSend() { document.getElementById("txtSend").innerText=""; } function clearReceive() { document.getElementById("txtReceive").innerText=""; } function startTime() { var today=new Date() var h=today.getHours() var m=today.getMinutes() var s=today.getSeconds() // add a zero in front of numbers<10 m=checkTime(m) s=checkTime(s) document.getElementById('lblTime').innerHTML=h+":"+m+":"+s t=setTimeout('startTime()',500) } function checkTime(i) { if (i<10) {i="0" + i} return i } --> </script> </head> <body onload="startTime()" onunload="closeComPort()"> <form name="form1"> <fieldset style="width:225px;height:180px;text-align:center;"> <legend>串口</legend> <div style="float:left;width:250px"> <br/> <span>串口号:</span> <select name="ComName" id="ComName" style="width:100px" > </select> <br/> <span>波特率:</span> <select name="BaudRate" id="BaudRate" style="width:100px" > <option value="9600" selected="selected">9600</option> <option value="57600" >57600</option> <option value="115200" >115200</option> <option value="1382400" >1382400</option> <option value="3000000" >3000000</option> </select> <br/> <br/> <input type="button" id="btnGetPort" style="width:80px;height:30px;font-size:13px" name="btnGetPort" value="获取串口" onclick="getComPorts()"/> <input type="button" id="btnOpenPort" style="width:80px;height:30px;font-size:13px" name="btnOpenPort" value="打开串口" onclick="connectComPort()"/> <input type="button" id="btnClearPort" style="width:80px;height:30px;font-size:13px" name="btnClearPort" value="清理串口" onclick="clearComPort()"/> <input type="button" id="btnClosePort" style="width:80px;height:30px;font-size:13px" name="btnClosePort" value="关闭串口" onclick="closeComPort()"/> </div> </fieldset> <br /><br /> <fieldset style="width:800px;height:150px;text-align:center;"> <legend>发送区域</legend> <div align="left">V6-握手指令: FF 55 01 01 FE</div> <div align="left">V6-50HZ采集:FF 55 05 03 20 4E 00 00 8A</div> <div align="left">V6-停止指令: FF 55 01 10 EF</div> <div style="float:left;"> <textarea id="txtSend" name="txtSend" style="width:800px;height:80px"></textarea> <br/> <input type="button" id="btnSend" style="width:100px;height:30px" name="btnSend" value="发送" onclick="writeString()"/> <input type="button" id="btnClearSend" style="width:100px;height:30px" name="btnClearSend" value="清空" onclick="clearSend()"/> </div> </fieldset> <br /><br /> <fieldset style="width:800px;height:500px;text-align:center;"> <legend>接收区域</legend> <div style="float:left;"> <textarea id="txtReceive" readonly="readonly" name="txtReceive" style="width:800px;height:430px"></textarea> <br/> <input type="button" id="btnClearReceive" style="width:100px;height:30px" name="btnClearReceive" value="清空" onclick="clearReceive()"/> </div> </fieldset> <span id="lblTime"></span> </form> <p> <object classid="clsid:6C6A0DE4-193A-48f5-BA91-3C180558785B" codebase="../WebSerialSetup.msi" width="442" height="87" id="webSerial" name="webSerial"> </object> </p> <!-- Attaching to an ActiveX event--> <script language="javascript" type="text/javascript"> function webSerial::OnReceive(dataString) { document.getElementById("txtReceive").value += dataString+"\r\n";; } </script> </body> </html>
View Code
在使用JS调用ActiveX的时候碰上问题一:方法可以成功调用,而事件却调用失败。网上文章大都是说JS如何调ActiveX,而ActiveX这边的方法或者事件需要满足什么条件才能被JS成功调用却少有涉及。正当我山穷水尽疑无路的时候,事情有了转折,无意中看到一篇老外写的文章。链接地址是:http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step。才知道事件需要实现一个接口才能被JS识别。所以这部分代码后面被加上去了:
/// <summary> /// Event handler for events that will be visible from JavaScript /// </summary> public delegate void ControlEventHandler(string dataString); /// <summary> /// This interface shows events to javascript /// </summary> [Guid("68BD4E0D-D7BC-4cf6-BEB7-CAB950161E79")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ControlEvents { //Add a DispIdAttribute to any members in the source interface to specify the COM DispId. [DispId(0x60020001)] void OnReceive(string dataString); //This method will be visible from JS }
控件类名前面也加上这个
[ClassInterface(ClassInterfaceType.AutoDual), ComSourceInterfaces(typeof(ControlEvents))]
事件定义如下:
public event ControlEventHandler OnReceive; [ComVisible(true)] private void Receive(string dataString) { if (OnReceive != null) { OnReceive(dataString); //Calling event that will be catched in JS } }
本地打开网页,执行全部功能,操作正常,大功告成!!!
随后我把网页在本地发布并使用局域网中其他电脑(操作系统WIN7)IE访问该网页。那么问题来了:
1:机器弹出对话框拒绝安装当前ActiveX。经过对IE internet选项设置,放开对无签名ActiveX访问限制后。有的机器能弹出安装对话框,有的机器仍然坚决禁止。而且就算是弹出安装对话框,在确认安装后,对话框消失,插件也没装上。。。
好吧,这个问题也是没搞明白啥原因。后面时间紧迫,只好给客户一个下载链接,自己去点击下载。
2:下载安装包并安装完毕后,在客户机器上操作网页功能。前面几个按钮功能都OK,但是在填入指令点击发送,网页出现崩溃重新刷新的情况,而且换了几台机器都是这样。后面想起在生成安装包的时候,有弹出一个对话框,提示Visual Studio registry capture utility 已停止工作。百度一番后,找到解决方法:在Microsoft Visual Studio 9.0/Common7/Tools/Deployment 路径下面的regcap.exe文件,点击右键在属性页面中,选择兼容性页面,选中“以兼容模式运行”框就好了。兼容win7 就行。
相应设置后,重新生成安装文件。。。在客户机上安装后,一切正常!!!
最后附上完整项目代码:http://pan.baidu.com/s/1hq8MzJ2
相关文章推荐
- C# Path类常用操作
- C#文件操作大全(SamWang)
- C#文件操作总结
- 【C#】:浅谈反射机制
- C#开发winform中OpenFileDialog的运用还可以多选
- 2.2.3 Main方法;2.2.4 标识符及关键字;2.2.5 C#语句
- c#中的??运算符
- C#模板引擎 RazorEngine3.7的扩展 — 引入外部文件
- C# 进制转换(二进制、十六进制、十进制互转)
- C# DataGridView改变行颜色
- 使用C#格式化字符串 ~
- C#中 使用 System.Windows.Forms.Time 定时器
- 第二章 C#继承&继承类型&虚函数&抽象类&抽象函数&抽象方法&隐藏方法
- 新手浅谈C#Task异步编程
- c#中的模态对话框和非模态对话框
- C# 中如何调用DLL文件(分两种情况,托管与非托管)
- C#中何时使用dynamic
- c#构造函数
- c# for与foreach
- C# 键盘勾勒 打开,隐藏,关闭,截屏快捷键