在网上查了一些资料也实际操作了一下,在此自己再作一次详细记录。
功能:将对机具操作的FK.dll封装成fk.ocx,注册后能在网页上对机器操作。
使用Visual Studio 2010 .NET Framework 2.0(C#)
开发ActiveX步骤:
2. 更改“项目属性-应用程序-程序集信息”设置,勾选“使程序集 COM 可见”
3.更改“项目属性-生成”设置,勾选“为 COM Interop 注册”(注意,此处如果实在debug状态下修改的,那在调到release状态下还需要再设置一次):
4.修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]项(需要引用System.Security名称空间):
5.添加一个Windows用户控件名称:DHFkAttendOCX(自已定义,可以将已有的更改名称)
6.为控件类添加GUID,这个编号将用于B/S系统的客户端调用时使用(可以使用 工具-创建GUID 菜单创建一个GUID,再复制):
7.为了让ActiveX控件获得客户端的信任,控件类还需要实现一个名为“IObjectSafety”的接口,要创建该接口(注意,不能修改该接口的GUID值),IObjectSafety.cs代码如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 namespace DHFkAttendOCX
6 {
7 [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
8 [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
9 public interface IObjectSafety
10 {
11 [PreserveSig]
12 int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
13 [PreserveSig()]
14 int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
15 }
16 }
8.然后在控件类中继承并实现该接口,可以直接复制不用作任何更改:
1 ////IObjectSafety 成员
2 #region IObjectSafety 成员
3
4 private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
5 private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
6 private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
7 private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
8 private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
9
10 private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
11 private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
12 private const int S_OK = 0;
13 private const int E_FAIL = unchecked((int)0x80004005);
14 private const int E_NOINTERFACE = unchecked((int)0x80004002);
15
16 private bool _fSafeForScripting = true;
17 private bool _fSafeForInitializing = true;
18
19 public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
20 {
21 int Rslt = E_FAIL;
22
23 string strGUID = riid.ToString("B");
24 pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
25 switch (strGUID)
26 {
27 case _IID_IDispatch:
28 case _IID_IDispatchEx:
29 Rslt = S_OK;
30 pdwEnabledOptions = 0;
31 if (_fSafeForScripting == true)
32 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
33 break;
34 case _IID_IPersistStorage:
35 case _IID_IPersistStream:
36 case _IID_IPersistPropertyBag:
37 Rslt = S_OK;
38 pdwEnabledOptions = 0;
39 if (_fSafeForInitializing == true)
40 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
41 break;
42 default:
43 Rslt = E_NOINTERFACE;
44 break;
45 }
46
47 return Rslt;
48 }
49
50 public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
51 {
52 int Rslt = E_FAIL;
53 string strGUID = riid.ToString("B");
54 switch (strGUID)
55 {
56 case _IID_IDispatch:
57 case _IID_IDispatchEx:
58 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
59 Rslt = S_OK;
60 break;
61 case _IID_IPersistStorage:
62 case _IID_IPersistStream:
63 case _IID_IPersistPropertyBag:
64 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
65 Rslt = S_OK;
66 break;
67 default:
68 Rslt = E_NOINTERFACE;
69 break;
70 }
71
72 return Rslt;
73 }
74
75
76 #endregion
9.引用自己想要封装的FK.dll
1 #region 引用dll方法
2 [DllImport("FK.dll")]
3 public static extern int FK_ConnectComm(int nMachineNo, int nComPort, int nBaudRate,
4 string pstrTelNumber, int nWaitDialTime, int nLicense, int nComTimeOut);
5 #endregion
10.封装
1 #region 封装方法
2 [SecurityCritical]
3 public int IDFK_ConnectNet(int nMachineNo, string strIpAddress, int nNetPort, int nTimeOut, int nProtocolType, int nNetPassword, int nLicense)
4 {
5 int result = FK_ConnectNet(nMachineNo, strIpAddress, nNetPort, nTimeOut, nProtocolType, nNetPassword, nLicense);
6 return result;
7 }
8 #endregion
11.打包并发布ActiveX,与普通的Windows Form应用程序的安装部署几乎一样,只有一个地方需要注意,将前面创建的用户控件项目作为主输出项目,并设置其Register属性为vsdrpCOM
12.给应用程序文件夹添加项目输出时,我们将DHFkAttendOCX项目添加进来,在项目中选择DHFkAttendOCX控件项目
13.将FK.dll和其它引用的dll都一并作为文件添加
14.在系统文件夹system32文件夹中将msiexec.exe(卸载控件时用到)地址找到也添加至上面文件夹
15.在“用户的程序菜单”中,新建文件夹后加入主程序与msiexec.exe快捷方式
16.点击安装项目工程,在属性中将ProductCode复制,点击msiexec.exe快捷方式,在属性Arguments中 加入"/x+一个空隔+ProductCode"
17.生成项目,打包文件就生成了,打开..\Debug看到生成了2个文件,一个是xx.exe,一个是xx.msi,执行exe安装到系统。
18.安装成功后, 在页面中添加<object id="csocx" classid="clsid:FE7EC23B-78A6-45B9-B61E-945970D963B6"></object>
"FE7EC23B-78A6-45B9-B61E-945970D963B6"为第6步生成的GUID
19.页面中js中引用
<script language="javascript" type="text/javascript">
//操作
function OnOpearOnMachion(opearValue) {
var ocxKq = document.getElementById("csocx");
var bolResult = ocxKq.IDFK_ConnectNet(1, "192.168.0.123", 5005, 3000, 0, 0, 123);
}
</script>
20.大功造成。
21.附代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Text;
7 using System.Windows.Forms;
8 using System.Runtime.InteropServices;
9 using System.Security;
10
11 namespace DHFkAttendOCX
12 {
13 [Guid("FE7EC23B-78A6-45B9-B61E-945970D963B6")]
14 [ProgId("DHFkAttend")]
15 public partial class DHFkAttendOCX : UserControl
16 {
17 public DHFkAttendOCX()
18 {
19 InitializeComponent();
20 }
21 ////IObjectSafety 成员
22 #region IObjectSafety 成员
23
24 private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
25 private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
26 private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
27 private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
28 private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
29
30 private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
31 private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
32 private const int S_OK = 0;
33 private const int E_FAIL = unchecked((int)0x80004005);
34 private const int E_NOINTERFACE = unchecked((int)0x80004002);
35
36 private bool _fSafeForScripting = true;
37 private bool _fSafeForInitializing = true;
38
39 public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
40 {
41 int Rslt = E_FAIL;
42
43 string strGUID = riid.ToString("B");
44 pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
45 switch (strGUID)
46 {
47 case _IID_IDispatch:
48 case _IID_IDispatchEx:
49 Rslt = S_OK;
50 pdwEnabledOptions = 0;
51 if (_fSafeForScripting == true)
52 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
53 break;
54 case _IID_IPersistStorage:
55 case _IID_IPersistStream:
56 case _IID_IPersistPropertyBag:
57 Rslt = S_OK;
58 pdwEnabledOptions = 0;
59 if (_fSafeForInitializing == true)
60 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
61 break;
62 default:
63 Rslt = E_NOINTERFACE;
64 break;
65 }
66
67 return Rslt;
68 }
69
70 public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
71 {
72 int Rslt = E_FAIL;
73 string strGUID = riid.ToString("B");
74 switch (strGUID)
75 {
76 case _IID_IDispatch:
77 case _IID_IDispatchEx:
78 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
79 Rslt = S_OK;
80 break;
81 case _IID_IPersistStorage:
82 case _IID_IPersistStream:
83 case _IID_IPersistPropertyBag:
84 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
85 Rslt = S_OK;
86 break;
87 default:
88 Rslt = E_NOINTERFACE;
89 break;
90 }
91
92 return Rslt;
93 }
94
95
96 #endregion
97
98 #region 引用dll方法
99 [DllImport("FK.dll")]
100 public static extern int FK_ConnectComm(int nMachineNo, int nComPort, int nBaudRate,
101 string pstrTelNumber, int nWaitDialTime, int nLicense, int nComTimeOut);
102 #endregion
103
104 #region 封装方法
105 [SecurityCritical]
106 public int IDFK_ConnectNet(int nMachineNo, string strIpAddress, int nNetPort, int nTimeOut, int nProtocolType, int nNetPassword, int nLicense)
107 {
108 int result = FK_ConnectNet(nMachineNo, strIpAddress, nNetPort, nTimeOut, nProtocolType, nNetPassword, nLicense);
109 return result;
110 }
111 #endregion
112 }
113 }
22.要注意的是,浏览器要设置以下控件才能正常运行
安装所需要的控件后:
打开IE浏览器,在菜单栏点击“工具”—“Internet选项”—“安全”选项卡。
1. 点击“受信任站点”
2.然后点击“站点”弹出如下图片:
3.按照上图填写内容后,点击“添加”然后点“确定”.
4. 设置自定义安全级别(internet本地、受信任站点均需要)
5.点击“自定义级别”,弹出如下图片,选择“安全级 – 低” 然后将组件全部“启用”: