您的位置:首页 > 编程语言 > C#

C# ActiveX开发及安装部署

2015-08-06 09:31 561 查看

  最近项目中,因为需要在WEB页面上操作串口,包括串口查询、打开、发送指令、接收数据、关闭串口等功能。如下所示:

  考虑使用ActiveX来实现。因为以前没有这方面的经验,开发过程中也是遇到各种问题。废话不多说,下面进入正题:

  1:打开VS2008,新建项目,以下是具体代码:

1 using System;
2 using System.Collections.Generic;
3 using System.Windows.Forms;
4 using System.IO.Ports;
5 using System.IO;
6 using System.Reflection;
7 using System.Runtime.InteropServices;
8 using mshtml;
9 using System.Text;
10 using Microsoft.Win32;
11 using System.Threading;
12
13 namespace WebSerial
14 {
15     [ProgId("WebSerial")]//控件名称
16     [ClassInterface(ClassInterfaceType.AutoDual), ComSourceInterfaces(typeof(ControlEvents))]
17     [Guid("6C6A0DE4-193A-48f5-BA91-3C180558785B")]//控件的GUID,用于COM注册和HTML中Object对象classid引用
18     [ComVisible(true)]
19     public partial class SerialPortControl : UserControl,IObjectSafety
20     {
21         ExSerialPort serialPort;
22         List%26lt;byte%26gt; buffer = new List%26lt;byte%26gt;(4096);
23
24         /// %26lt;summary%26gt;
25         /// 是否准备关闭串口
26         /// %26lt;/summary%26gt;
27         private static bool m_IsTryToClosePort = false;
28         /// %26lt;summary%26gt;
29         /// 是否正在接收数据
30         /// %26lt;/summary%26gt;
31         private static bool m_IsReceiving = false;
32         public SerialPortControl()
33         {
34
35         }
36
37         /// %26lt;summary%26gt;
38         /// 获取本地串口列表,以逗号隔开
39         /// %26lt;/summary%26gt;
40         /// %26lt;returns%26gt;%26lt;/returns%26gt;
41         public string getComPorts()
42         {
43             string ports = "";
44             foreach (string s in ExSerialPort.GetPortNames())
45             {
46                 ports += "," + s;
47             }
48             return ports.Length %26gt; 0 ? ports.Substring(1) : "";
49         }
50
51         /// %26lt;summary%26gt;
52         /// 以指定串口号和波特率连接串口
53         /// %26lt;/summary%26gt;
54         /// %26lt;param name="com"%26gt;端口号%26lt;/param%26gt;
55         /// %26lt;param name="baudRate"%26gt;波特率%26lt;/param%26gt;
56         /// %26lt;returns%26gt;%26lt;/returns%26gt;
57         [ComVisible(true)]
58         public string connect(string com, int baudRate)
59         {
60             close();
61             serialPort = null;
62             serialPort = new ExSerialPort(com);
63             serialPort.BaudRate = baudRate;
64             serialPort.Parity = Parity.None;
65             serialPort.DataBits = 8;
66             serialPort.Encoding = Encoding.ASCII;
67             serialPort.ReceivedBytesThreshold = 5;
68             serialPort.ReadBufferSize = 102400;
69
70             try
71             {
72                 serialPort.Open();
73                 if (serialPort.IsOpen)
74                 {
75                     m_IsTryToClosePort = false;
76                     this.clear();
77                     serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
78                     return "true";
79                 }
80             }
81             catch { }
82
83             return "false";
84         }
85
86         /// %26lt;summary%26gt;
87         /// 清理串口数据并关闭串口
88         /// %26lt;/summary%26gt;
89         [ComVisible(true)]
90         public void close()
91         {
92             m_IsTryToClosePort = true;
93             while (m_IsReceiving)
94             {
95                 Application.DoEvents();
96             }
97
98             if (serialPort != null)
99             {
100                 serialPort.Dispose();
101             }
102         }
103
104         /// %26lt;summary%26gt;
105         /// 清理串口数据
106         /// %26lt;/summary%26gt;
107         [ComVisible(true)]
108         public void clear()
109         {
110             if (serialPort != null %26amp;%26amp; serialPort.IsOpen)
111             {
112                 serialPort.Clear();
113             }
114         }
115
116         /// %26lt;summary%26gt;
117         /// 发送字符串
118         /// %26lt;/summary%26gt;
119         /// %26lt;param name="s"%26gt;%26lt;/param%26gt;
120         [ComVisible(true)]
121         public void writeString(string hexString)
122         {
123             if (serialPort != null %26amp;%26amp; serialPort.IsOpen)
124             {
125                 byte[] bytes = strToToHexByte(hexString);
126                 serialPort.Write(bytes, 0, bytes.Length);
127             }
128         }
129
130         /// %26lt;summary%26gt;
131         /// 字符串转16进制字节数组
132         /// %26lt;/summary%26gt;
133         /// %26lt;param name="hexString"%26gt;%26lt;/param%26gt;
134         /// %26lt;returns%26gt;%26lt;/returns%26gt;
135         private static byte[] strToToHexByte(string hexString)
136         {
137             hexString = hexString.Replace(" ", "");
138             if ((hexString.Length % 2) != 0)
139                 hexString += " ";
140             byte[] returnBytes = new byte[hexString.Length / 2];
141             for (int i = 0; i %26lt; returnBytes.Length; i++)
142                 returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
143             return returnBytes;
144         }
145
146         ///  %26lt;summary%26gt;
147         /// 字节数组转字符串16进制
148         ///  %26lt;/summary%26gt;
149         ///  %26lt;param name="InBytes"%26gt; 二进制字节 %26lt;/param%26gt;
150         ///  %26lt;returns%26gt;类似"01 02 0F" %26lt;/returns%26gt;
151         public static string ByteToString(byte[] InBytes)
152         {
153             string StringOut = "";
154             foreach (byte InByte in InBytes)
155             {
156                 //StringOut += String.Format("{0:X2}", InByte) + " ";
157                 StringOut += " " + InByte.ToString("X").PadLeft(2, '0');
158             }
159
160             return StringOut.Trim();
161         }
162
163         /// %26lt;summary%26gt;
164         /// 接收数据
165         /// %26lt;/summary%26gt;
166         /// %26lt;param name="sender"%26gt;%26lt;/param%26gt;
167         /// %26lt;param name="e"%26gt;%26lt;/param%26gt;
168         void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
169         {
170             if (m_IsTryToClosePort)
171             {
172                 return;
173             }
174
175             m_IsReceiving = true;
176
177             try
178             {
179                 int n = serialPort.BytesToRead;
180                 if (n %26gt; 0)
181                 {
182                     byte[] buf = new byte
;
183                     serialPort.Read(buf, 0, n);
184                     string dataString = ByteToString(buf);
185                     Receive(dataString);
186                 }
187
188                 ////1.缓存数据
189                 //buffer.AddRange(buf);
190                 ////2.完整性判断
191                 //while (buffer.Count %26gt;= 5) //至少包含帧头(2字节)、长度(1字节)、校验位(1字节);根据设计不同而不同
192                 //{
193                 //    //2.1 查找数据头
194                 //    if (buffer[0] == 0xff %26amp;%26amp; buffer[1] == 0x55) //传输数据有帧头,用于判断
195                 //    {
196                 //        int len = buffer[2];
197                 //        if (buffer.Count %26lt; len + 4) //数据区尚未接收完整
198                 //        {
199                 //            break;
200                 //        }
201                 //        //得到完整的数据,复制到ReceiveBytes中进行校验
202                 //        byte[] ReceiveBytes = new byte[len + 4];
203                 //        buffer.CopyTo(0, ReceiveBytes, 0, len + 4);
204
205                 //        byte checkByte = ReceiveBytes[len + 3];//获取校验字节
206                 //        byte realCheckByte = 0x00;
207                 //        realCheckByte -= buffer[2];
208                 //        for (int packIndex = 0; packIndex %26lt; len; packIndex++)//将后面的数据加起来
209                 //        {
210                 //            realCheckByte -= ReceiveBytes[packIndex + 3];
211                 //        }
212
213                 //        if (checkByte == realCheckByte)//验证,看数据是否合格
214                 //        {
215                 //            string dataString = ByteToString(ReceiveBytes);
216                 //            Receive(dataString);
217                 //        }
218                 //        buffer.RemoveRange(0, len + 4);
219                 //    }
220                 //    else //帧头不正确时,清除
221                 //    {
222                 //        buffer.RemoveAt(0);
223                 //    }
224
225                 //}
226             }
227             finally
228             {
229                 m_IsReceiving = false;
230             }
231         }
232
233         public event ControlEventHandler OnReceive;
234         [ComVisible(true)]
235         private void Receive(string dataString)
236         {
237             if (OnReceive != null)
238             {
239                 OnReceive(dataString); //Calling event that will be catched in JS
240             }
241         }
242
243         ///    %26lt;summary%26gt;
244         ///    Register the class as a    control    and    set    it's CodeBase entry
245         ///    %26lt;/summary%26gt;
246         ///    %26lt;param name="key"%26gt;The registry key of the control%26lt;/param%26gt;
247         [ComRegisterFunction()]
248         public static void RegisterClass(string key)
249         {
250             // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
251             StringBuilder sb = new StringBuilder(key);
252
253             sb.Replace(@"HKEY_CLASSES_ROOT\", "");
254             // Open the CLSID\{guid} key for write access
255             RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
256
257             // And create    the    'Control' key -    this allows    it to show up in
258             // the ActiveX control container
259             RegistryKey ctrl = k.CreateSubKey("Control");
260             ctrl.Close();
261
262             // Next create the CodeBase entry    - needed if    not    string named and GACced.
263             RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
264             inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
265             inprocServer32.Close();
266             // Finally close the main    key
267             k.Close();
268             MessageBox.Show("Registered");
269         }
270
271         ///    %26lt;summary%26gt;
272         ///    Called to unregister the control
273         ///    %26lt;/summary%26gt;
274         ///    %26lt;param name="key"%26gt;Tke registry key%26lt;/param%26gt;
275         [ComUnregisterFunction()]
276         public static void UnregisterClass(string key)
277         {
278             StringBuilder sb = new StringBuilder(key);
279             sb.Replace(@"HKEY_CLASSES_ROOT\", "");
280
281             // Open    HKCR\CLSID\{guid} for write    access
282             RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
283
284             // Delete the 'Control'    key, but don't throw an    exception if it    does not exist
285             k.DeleteSubKey("Control", false);
286
287             // Next    open up    InprocServer32
288             //RegistryKey    inprocServer32 =
289             k.OpenSubKey("InprocServer32", true);
290
291             // And delete the CodeBase key,    again not throwing if missing
292             k.DeleteSubKey("CodeBase", false);
293
294             // Finally close the main key
295             k.Close();
296             MessageBox.Show("UnRegistered");
297         }
298
299         #region IObjectSafety 成员
300         public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
301         {
302             pdwSupportedOptions = 1;
303             pdwEnabledOptions = 2;
304         }
305         public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
306         {
307             throw new NotImplementedException();
308         }
309         #endregion
310
311         #region IObjectSafety 成员
312
313         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
314         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
315         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
316         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
317         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
318
319         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
320         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
321         private const int S_OK = 0;
322         private const int E_FAIL = unchecked((int)0x80004005);
323         private const int E_NOINTERFACE = unchecked((int)0x80004002);
324
325         private bool _fSafeForScripting = true;
326         private bool _fSafeForInitializing = true;
327
328
329         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
330         {
331             int Rslt = E_FAIL;
332
333             string strGUID = riid.ToString("B");
334             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
335             switch (strGUID)
336             {
337                 case _IID_IDispatch:
338                 case _IID_IDispatchEx:
339                     Rslt = S_OK;
340                     pdwEnabledOptions = 0;
341                     if (_fSafeForScripting == true)
342                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
343                     break;
344                 case _IID_IPersistStorage:
345                 case _IID_IPersistStream:
346                 case _IID_IPersistPropertyBag:
347                     Rslt = S_OK;
348                     pdwEnabledOptions = 0;
349                     if (_fSafeForInitializing == true)
350                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
351                     break;
352                 default:
353                     Rslt = E_NOINTERFACE;
354                     break;
355             }
356
357             return Rslt;
358         }
359
360         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
361         {
362             int Rslt = E_FAIL;
363
364             string strGUID = riid.ToString("B");
365             switch (strGUID)
366             {
367                 case _IID_IDispatch:
368                 case _IID_IDispatchEx:
369                     if (((dwEnabledOptions %26amp; dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) %26amp;%26amp;
370                          (_fSafeForScripting == true))
371                         Rslt = S_OK;
372                     break;
373                 case _IID_IPersistStorage:
374                 case _IID_IPersistStream:
375                 case _IID_IPersistPropertyBag:
376                     if (((dwEnabledOptions %26amp; dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) %26amp;%26amp;
377                          (_fSafeForInitializing == true))
378                         Rslt = S_OK;
379                     break;
380                 default:
381                     Rslt = E_NOINTERFACE;
382                     break;
383             }
384
385             return Rslt;
386         }
387
388         #endregion
389     }
390
391     /// %26lt;summary%26gt;
392     /// Event handler for events that will be visible from JavaScript
393     /// %26lt;/summary%26gt;
394     public delegate void ControlEventHandler(string dataString);
395
396     /// %26lt;summary%26gt;
397     /// This interface shows events to javascript
398     /// %26lt;/summary%26gt;
399     [Guid("68BD4E0D-D7BC-4cf6-BEB7-CAB950161E79")]
400     [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
401     public interface ControlEvents
402     {
403         //Add a DispIdAttribute to any members in the source interface to specify the COM DispId.
404         [DispId(0x60020001)]
405         void OnReceive(string dataString); //This method will be visible from JS
406     }
407
408     public class ExSerialPort : SerialPort
409     {
410         public ExSerialPort(string name)
411             : base(name)
412         {
413         }
414
415         public void Clear()
416         {
417             try
418             {
419                 if (this.IsOpen)
420                 {
421                     this.DiscardInBuffer();
422                     this.DiscardOutBuffer();
423                 }
424             }
425             catch { }
426         }
427
428         protected override void Dispose(bool disposing)
429         {
430             Clear();
431
432             var stream = (Stream)typeof(SerialPort).GetField("internalSerialStream", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this);
433
434             if (stream != null)
435             {
436                 stream.Dispose();
437             }
438
439             base.Dispose(disposing);
440         }
441     }
442 }
View Code

  2:新建安装项目,将上面项目DLL打包生成Msi安装文件。这里不多说,网上大把文章教你怎么做。

  3:新建Web项目,具体代码如下:

1 %26lt;html%26gt;
2 %26lt;head%26gt;
3 %26lt;title%26gt;JavaScript串口测试%26lt;/title%26gt;
4 %26lt;meta http-equiv="Content-Type" content="text/html; charset=GB2312" /%26gt;
5 %26lt;script   language="javascript"   type="text/javascript"%26gt;
6 %26lt;!--
7     function getComPorts()
8     {
9         var ports = webSerial.getComPorts();
10         var arr = ports.split(',');
11         var ctl = document.getElementById("ComName");
12         if(ctl)
13         {
14             ctl.options.length = 0;
15             for(var i=0;i%26lt;arr.length;i++)
16             {
17                 ctl.options[i] = new Option(arr[i],arr[i]);
18             }
19         }
20    }
21
22     function connectComPort()
23     {
24         var com = document.getElementById("ComName").value.toString();
25         var baudRate = document.getElementById("BaudRate").value;
26         var result = webSerial.connect(com,baudRate);
27         alert(result);
28     }
29
30     function clearComPort()
31     {
32         webSerial.clear();
33         alert("清理串口成功!");
34     }
35
36     function closeComPort()
37     {
38         webSerial.close();
39         alert("关闭串口成功!");
40     }
41
42     function writeString()
43     {
44         var hexString = document.getElementById("txtSend").value.toString();
45         webSerial.writeString(hexString);
46         alert("发送指令成功!");
47     }
48
49     function clearSend()
50     {
51         document.getElementById("txtSend").innerText="";
52     }
53
54     function clearReceive()
55     {
56         document.getElementById("txtReceive").innerText="";
57     }
58
59     function startTime()
60     {
61         var today=new Date()
62         var h=today.getHours()
63         var m=today.getMinutes()
64         var s=today.getSeconds()
65         // add a zero in front of numbers%26lt;10
66         m=checkTime(m)
67         s=checkTime(s)
68         document.getElementById('lblTime').innerHTML=h+":"+m+":"+s
69         t=setTimeout('startTime()',500)
70     }
71
72     function checkTime(i)
73     {
74         if (i%26lt;10)
75           {i="0" + i}
76           return i
77     }
78
79 --%26gt;
80 %26lt;/script%26gt;
81
82 %26lt;/head%26gt;
83 %26lt;body onload="startTime()" onunload="closeComPort()"%26gt;
84 %26lt;form name="form1"%26gt;
85 %26lt;fieldset style="width:225px;height:180px;text-align:center;"%26gt;
86    %26lt;legend%26gt;串口%26lt;/legend%26gt;
87    %26lt;div style="float:left;width:250px"%26gt;
88        %26lt;br/%26gt;
89        %26lt;span%26gt;串口号:%26lt;/span%26gt;
90        %26lt;select name="ComName" id="ComName" style="width:100px" %26gt;
91        %26lt;/select%26gt;
92        %26lt;br/%26gt;
93        %26lt;span%26gt;波特率:%26lt;/span%26gt;
94    %26lt;select name="BaudRate" id="BaudRate" style="width:100px" %26gt;
95    %26lt;option value="9600" selected="selected"%26gt;9600%26lt;/option%26gt;
96    %26lt;option value="57600"  %26gt;57600%26lt;/option%26gt;
97    %26lt;option value="115200" %26gt;115200%26lt;/option%26gt;
98    %26lt;option value="1382400" %26gt;1382400%26lt;/option%26gt;
99    %26lt;option value="3000000" %26gt;3000000%26lt;/option%26gt;
100    %26lt;/select%26gt;
101    %26lt;br/%26gt;
102        %26lt;br/%26gt;
103        %26lt;input   type="button" id="btnGetPort" style="width:80px;height:30px;font-size:13px"   name="btnGetPort"   value="获取串口"   onclick="getComPorts()"/%26gt;
104        %26lt;input   type="button" id="btnOpenPort" style="width:80px;height:30px;font-size:13px"   name="btnOpenPort"   value="打开串口"   onclick="connectComPort()"/%26gt;
105        %26lt;input   type="button" id="btnClearPort" style="width:80px;height:30px;font-size:13px"   name="btnClearPort"   value="清理串口"   onclick="clearComPort()"/%26gt;
106        %26lt;input   type="button" id="btnClosePort" style="width:80px;height:30px;font-size:13px"   name="btnClosePort"   value="关闭串口"   onclick="closeComPort()"/%26gt;
107     %26lt;/div%26gt;
108 %26lt;/fieldset%26gt;
109 %26lt;br /%26gt;%26lt;br /%26gt;
110 %26lt;fieldset style="width:800px;height:150px;text-align:center;"%26gt;
111    %26lt;legend%26gt;发送区域%26lt;/legend%26gt;
112    %26lt;div align="left"%26gt;V6-握手指令: FF 55 01 01 FE%26lt;/div%26gt;
113    %26lt;div align="left"%26gt;V6-50HZ采集:FF 55 05 03 20 4E 00 00 8A%26lt;/div%26gt;
114    %26lt;div align="left"%26gt;V6-停止指令: FF 55 01 10 EF%26lt;/div%26gt;
115    %26lt;div style="float:left;"%26gt;
116        %26lt;textarea id="txtSend"  name="txtSend" style="width:800px;height:80px"%26gt;%26lt;/textarea%26gt;
117        %26lt;br/%26gt;
118        %26lt;input   type="button" id="btnSend" style="width:100px;height:30px"   name="btnSend"   value="发送"   onclick="writeString()"/%26gt;
119        %26lt;input  type="button" id="btnClearSend" style="width:100px;height:30px"   name="btnClearSend"   value="清空"   onclick="clearSend()"/%26gt;
120    %26lt;/div%26gt;
121 %26lt;/fieldset%26gt;
122 %26lt;br /%26gt;%26lt;br /%26gt;
123 %26lt;fieldset style="width:800px;height:500px;text-align:center;"%26gt;
124    %26lt;legend%26gt;接收区域%26lt;/legend%26gt;
125    %26lt;div style="float:left;"%26gt;
126    %26lt;textarea id="txtReceive"  readonly="readonly" name="txtReceive" style="width:800px;height:430px"%26gt;%26lt;/textarea%26gt;
127    %26lt;br/%26gt;
128    %26lt;input  type="button" id="btnClearReceive" style="width:100px;height:30px"   name="btnClearReceive"   value="清空"   onclick="clearReceive()"/%26gt;
129    %26lt;/div%26gt;
130 %26lt;/fieldset%26gt;
131 %26lt;span id="lblTime"%26gt;%26lt;/span%26gt;
132 %26lt;/form%26gt;
133
134 %26lt;p%26gt;
135
136 %26lt;object classid="clsid:6C6A0DE4-193A-48f5-BA91-3C180558785B" codebase="../WebSerialSetup.msi" width="442" height="87" id="webSerial" name="webSerial"%26gt;
137         %26lt;/object%26gt;
138 %26lt;/p%26gt;
139
140  %26lt;!-- Attaching to an ActiveX event--%26gt;
141 %26lt;script language="javascript" type="text/javascript"%26gt;
142     function webSerial::OnReceive(dataString)
143     {
144         document.getElementById("txtReceive").value += dataString+"\r\n";;
145     }
146 %26lt;/script%26gt;
147 %26lt;/body%26gt;
148 %26lt;/html%26gt;
View Code

%26nbsp; %26nbsp; %26nbsp; 在使用JS调用ActiveX的时候碰上问题一:方法可以成功调用,而事件却调用失败。网上文章大都是说JS如何调ActiveX,而ActiveX这边的方法或者事件需要满足什么条件才能被JS成功调用却少有涉及。正当我山穷水尽疑无路的时候,事情有了转折,无意中看到一篇老外写的文章。链接地址是:http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step。才知道事件需要实现一个接口才能被JS识别。所以这部分代码后面被加上去了:

  

/// %26lt;summary%26gt;
/// Event handler for events that will be visible from JavaScript
/// %26lt;/summary%26gt;
public delegate void ControlEventHandler(string dataString);

/// %26lt;summary%26gt;
/// This interface shows events to javascript
/// %26lt;/summary%26gt;
[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
}
}

  本地打开网页,执行全部功能,操作正常,大功告成!!!

%26nbsp;

  随后我把网页在本地发布并使用局域网中其他电脑(操作系统WIN7)IE访问该网页。那么问题来了:

  1:机器弹出对话框拒绝安装当前ActiveX。经过对IE internet选项设置,放开对无签名ActiveX访问限制后。有的机器能弹出安装对话框,有的机器仍然坚决禁止。而且就算是弹出安装对话框,在确认安装后,对话框消失,插件也没装上。。。

  好吧,这个问题也是没搞明白啥原因。后面时间紧迫,只好给客户一个下载链接,自己去点击下载。

  2:下载安装包并安装完毕后,在客户机器上操作网页功能。前面几个按钮功能都OK,但是在填入指令点击发送,网页出现崩溃重新刷新的情况,而且换了几台机器都是这样。后面想起在生成安装包的时候,有弹出一个对话框,提示Visual Studio registry capture utility 已停止工作。百度一番后,找到解决方法:在Microsoft%26nbsp;Visual%26nbsp;Studio%26nbsp;9.0/Common7/Tools/Deployment%26nbsp;路径下面的regcap.exe文件,点击右键在属性页面中,选择兼容性页面,选中%26ldquo;以兼容模式运行%26rdquo;框就好了。兼容win7%26nbsp;就行。

相应设置后,重新生成安装文件。。。在客户机上安装后,一切正常!!!

  







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: