在網上查了一些資料也實際操作了一下,在此自己再作一次詳細記錄。
功能:將對機具操作的FK.dll封裝成fk.ocx,注冊后能在網頁上對機器操作。
使用Visual Studio 2010 .NET Framework 2.0(C#)
開發ActiveX步驟:
- 創建一個應用程序解決方案,並添加一個Windows控件庫項目
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.點擊“自定義級別”,彈出如下圖片,選擇“安全級 – 低” 然后將組件全部“啟用”: