c#封裝ActiveX接口實踐分析


       ActiveX接口 是一個開放的集成平台,為開發人員、用戶和 Web生產商提供了一個快速而簡便的在 Internet 和 Intranet 創建程序集成和內容的方法。 使用 ActiveX, 可輕松方便的在 Web頁中插入 多媒體效果、 交互式對象、以及復雜程序,創建用戶體驗相當的高質量多媒體 CD-ROM

      簡單的說,用activeX和js差不多,但是有些是js無法實現的,這個時候就可以考慮一下activeX,一般要求是在客戶端執行的程序,比如對本機的串口操作等,而服務器端不用做任何的操作和加載任何的插件,下面來簡單介紹下如何用C#自己封裝一個activeX組件,並在web中應用。

    說明:我的這個例子是在實際工作中,需要把第三方廠家的C/S端動態庫,封裝為B/S端動態庫。如果您的動態庫不調用第三方廠家的動態庫,可以在接口中去除鏈接即可。

    開發工具:VisualStudio2012 (VisualStudio2017在添加用戶控件后,自動生成匹配的程序代碼集,故不推薦!)

 

   步驟一:搭建開發環境

           說明:選擇類庫,編輯好名稱和路徑位置。

   

 

 步驟二: 更改“項目屬性-應用程序-程序集信息”設置,勾選“使程序集 COM 可見

           說明:勾選COM有2處,都需要勾選

          第一處:

           

         第二處:

          

    步驟三: 修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]項(需要引用System.Security名稱空間)

         

   

     步驟三: 添加一個Windows用戶控件

        

        

 步驟四:防止瀏覽器一直彈出安全警告

      為了提高程序的安全性,以便在客戶端安裝的時候在瀏覽器提高信任度,我們需要實現接口IObjectSafety    

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using System.Runtime.InteropServices;
 5 
 6 namespace mProjectName
 7 {
 8     [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
 9     [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
10     public interface IObjectSafety
11     {
12         [PreserveSig]
13         int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
14 
15         [PreserveSig()]
16         int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
17     }
18 }
IObjectSafety

     該類只是一個接口而已,我們還需要在自己的接口中去實現具體的方法。具體放置位置如下

     提示:這部分代碼都是通用的,不必做任何修改。

     

 步驟五:用戶控件的編寫

   

    首先,用戶控件的設計部分:XXX.Designer.cs的模塊,最好需要弄點圖片或者文字加載到上面去,一邊用瀏覽器加載的時候方便判斷是否加載成功。

   其次,編寫主接口模塊:

   

    首先,第一個接口  ItfLyCnIcObject是用來給家口注冊后,提供函數名稱的,您可以用這個函數實現不懂的功能,當然接口的函數還沒有實現的,是在下面的XXX_BObject 接口里面實現的。

       ItfLyCnIcObject接口代碼示例:

   

     主體XXXIc_Object接口代碼示例:

     

    主體XXXIc_Object接口代碼分為3部分,函數定義是為了加載第三方廠家的接口路徑和方法,以及參數等,IObjectSafety接口是通用的,實現之前的IObjectSafety接口方法的具體實現,下面的具體方法是實現 ItfLyCnIcObject接口中方法的具體實現

    

       IObjectSafety接口方法是公用的,無需修改:

 1         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
 2         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
 3         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
 4         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
 5         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
 6 
 7         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
 8         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
 9         private const int S_OK = 0;
10         private const int E_FAIL = unchecked((int)0x80004005);
11         private const int E_NOINTERFACE = unchecked((int)0x80004002);
12 
13         private bool _fSafeForScripting = true;
14         private bool _fSafeForInitializing = true;
15 
16 
17         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
18         {
19             int Rslt = E_FAIL;
20 
21             string strGUID = riid.ToString("B");
22             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
23             switch (strGUID)
24             {
25                 case _IID_IDispatch:
26                 case _IID_IDispatchEx:
27                     Rslt = S_OK;
28                     pdwEnabledOptions = 0;
29                     if (_fSafeForScripting == true)
30                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
31                     break;
32                 case _IID_IPersistStorage:
33                 case _IID_IPersistStream:
34                 case _IID_IPersistPropertyBag:
35                     Rslt = S_OK;
36                     pdwEnabledOptions = 0;
37                     if (_fSafeForInitializing == true)
38                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
39                     break;
40                 default:
41                     Rslt = E_NOINTERFACE;
42                     break;
43             }
44 
45             return Rslt;
46         }
47 
48         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
49         {
50             int Rslt = E_FAIL;
51 
52             string strGUID = riid.ToString("B");
53             switch (strGUID)
54             {
55                 case _IID_IDispatch:
56                 case _IID_IDispatchEx:
57                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
58                             (_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) &&
65                             (_fSafeForInitializing == true))
66                         Rslt = S_OK;
67                     break;
68                 default:
69                     Rslt = E_NOINTERFACE;
70                     break;
71             }
72 
73             return Rslt;
74         }
IObjectSafety接口具體實現

       ItfLyCnIcObject中的方法實現中的方法名稱和具體參數,以及個數都必須一致

            

        之后,再從新生成無誤后,會在bin文件的Debug文件中生成你封裝好的dll

             

 步驟六:注冊該接口

         這個得到的dll要和第三方廠家的dll放到一起(就是我們之前圖片中的哪個第三方廠家的DLL),一並放到C:\Windows\SYSWOW64目錄下,因為我的是windows64位電腦,如果你的電腦是32位的,一般放置到C:\Windows\System32目錄下。

       之后打開CMD,寫入一下注冊字符:

      "C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" /codebase C:\Windows\SysWOW64\XXXXc_B.dll

      具體截圖如下:

       

    然后回車即可注冊成功。(中間可能有警告,不用管,只要有注冊成功字樣即可)

 步驟七:接口的唯一ClassID查看

              這個ClassID就是瀏覽器識別該該接口的唯一憑證,也就是說有了這個ClassID,一台電腦原則上可以注冊無數的這種接口。可以通過接口查看器查看

              我用的查看工具是oleview,大家可以用其他的看看,一般只要是正確的注冊,都可以看到接口名稱,如果沒有看到,怎么能夠接口沒有注冊成功。

              

      步驟八:調用接口

     新建一個html頁面,添加下面的代碼

    

     具體代碼分析:

     

         到此,就基本上結束了,頁面可以用JS來調用了,另外,瀏覽器的安全設置大家最好按網上其他大神說的那樣設置就好。

         由於這個是實際項目中的上線代碼,故,內容可以不能全部公開,部分關鍵字段也做了刷白處理,可能對您觀看造成不便,請多多包涵。如果大家有興趣或者疑問,歡迎大家把疑問發送到我的郵箱1732182169@qq.com,或者直接QQ:1732182169聯系我,大家一起學習探討!

 

另外可以參考下面這位大神寫的,也很不錯:http://www.cnblogs.com/shuang121/archive/2012/06/04/2534296.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM