<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用反射動態調用ActiveX控件

      使用反射動態調用ActiveX控件

      袁永福 2018-3-2

      ■■■■問題描述:

      目前的基于.NET平臺的軟件研發中仍然存在大量的對COM及ActiveX控件的調用。使用C#調用ActiveX控件時一般是使用vs.net工具的添加COM引用時自動生成的互操作性程序集。這種方法操作簡單,能保證一定的性能。但會產生額外的程序文件,不利于應用軟件的簡潔部署。而且當開發環境和運行環境使用的ActiveX控件的版本不一致[袁永福原創]時還容易出錯。

      筆者長期從事基于.NET平臺的通用產品類軟件研發。[袁永福原創]產品類軟件要求部署簡潔,為此筆者都會將多個工程編譯生成的多個.NET程序集文件合并成一個.NET程序集文件來做到簡潔部署。

      實踐中發現自動生成的互操作性程序集無法合并。另外產品類軟件應該能適應各種復雜的開發和生產環境,甚至ActiveX控件的CLSID 都有可能變化。

      例如,對于COM類庫“HebcaFormSealLib”,VS.NET會自動生成程序集文件“AxInterop.HebcaFormSealLib.dll”、“Interop.HebcaFormSealLib.dll”。這些程序集文件無法進行程序集合并,而且對于32位或64位的工程項目類型敏感,容易導致錯誤。

      ■■■■技術改進:

      因此筆者不采用這種自動生成的互操作性程序集。轉而采用自定義的反射來調用ActiveX控件。

      后期綁定ActiveX 控件主要知識點為System.Windows.Forms.AxHost類型和Type.InvokeMember方法。

      AxHost類型是從System.Windows.Forms.Control類型[袁永福原創]派生出來的,專門用于承載ActiveX控件。它是一個抽象類,有一個受保護的構造函數,函數參數是一個guid格式的ActiveX控件的CLSID字符串。還有一個GetOcx內部方法用于創建ActiveX控件的對象實例,它是一個COM對象引用。

      創建了這個COM對象引用后就可以調用Type.InvokerMember方法來動態的調用指定名稱的方法和屬性。

      ■■■■范例:

      筆者最近在使用某電子簽名的ActiveX控件來實現文檔簽名的功能。筆者寫出以下接口代碼

      [System.Runtime.InteropServices.ComVisible(false)]
      public class DCHebeiCAControl : System.Windows.Forms.AxHost
      {
          public DCHebeiCAControl()
              : base("{e4ee564c-0845-4404-91ee-0c206113333f}")
          { }
      
          public object _ocx = null;
          protected override void AttachInterfaces()
          {
              this._ocx = base.GetOcx();
          }
          private void CheckOCX()
          {
              if (this._ocx == null)
              {
                  throw new System.NullReferenceException("_ocx");
              }
          }
          public VersionType GetBaseVersionType()
          {
              this.CheckOCX();
              VersionType result = (VersionType)this._ocx.GetType().InvokeMember(
                  "GetBaseVersionType",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { });
              return result;
          }
      
          public string GetCert(string sealSN)
          {
              this.CheckOCX();
              string result = (string)this._ocx.GetType().InvokeMember(
                  "GetCert",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { sealSN });
              return result;
          }
      
          public string GetClientDetailVersionInfo()
          {
              this.CheckOCX();
              string result = (string)this._ocx.GetType().InvokeMember(
                  "GetClientDetailVersionInfo",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { });
              return result;
          }
      
          public int GetClientVersion()
          {
              this.CheckOCX();
              int result = (int)this._ocx.GetType().InvokeMember(
                  "GetClientVersion",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { });
              return result;
          }
      
          public string GetClientVersionInfo()
          {
              this.CheckOCX();
              string result = (string)this._ocx.GetType().InvokeMember(
                  "GetClientVersionInfo",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { });
              return result;
          }
      
          public object GetConfig(string argName)
          {
              this.CheckOCX();
              object result = (object)this._ocx.GetType().InvokeMember(
                  "GetConfig",
                  BindingFlags.InvokeMethod,
                  null,
                  this._ocx,
                  new object[] { argName });
              return result;
          }
          // ----------- 封裝其他接口 -----------------------------
      }//classDCHebeiCAControl
      

       

      上述代碼中各個功能函數內部代碼結構簡單[袁永福原創],之間有很大的相似性,因此完全可以編寫一個代碼生成器來自動生成上述代碼。

      完成自定義的控件后,筆者再創建一個WinForm 窗體,在其Load事件中創建控件并添加到窗體上,其代碼如下

      private DCHebeiCAControl _Control = null;
      
      private void frmTest_Load(object sender, EventArgs e)
      {
          this._Control = new DCHebeiCAControl();
          this._Control.Size = new Size(200, 200);
          this._Control.Location = new Point(0, 0);
          this.Controls.Add(this._Control);
      }
      

       

      這樣無需使用自動生成的COM接口程序集即可調用ActiveX控件,大幅提高程序的通用性,而且對于32位和64位的項目類型不敏感。方便部署和更新。

      不過這樣由于采用后期綁定而帶來一定的性能[袁永福原創]問題,因此對于性能敏感而又頻繁調用ActiveX控件的場景下需要謹慎采用這種模式。

       

      ■■■■小結:

      在.net開發中調用舊的ActiveX控件是很多開發場景中不得不做的事情。在本文中,筆者介紹了在C#中調用ActiveX控件的標準模式,并提出了一種[袁永福原創]改良模式來提高程序的通用性。為操作ActiveX控件的.NET程序開發提供了一種新的技術手段。

      posted on 2018-03-04 14:31  袁永福 電子病歷,醫療信息化  閱讀(688)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 亚洲色在线V中文字幕| 乐昌市| 亚洲色最新高清AV网站| a级黑人大硬长爽猛出猛进| 亚洲av永久无码精品漫画| 日本一区二区三深夜不卡| 欧美日韩精品一区二区三区高清视频| 国产情侣激情在线对白| 国产午夜精品福利91| 国产在线精品中文字幕| 人妻少妇精品中文字幕| 日本一区二区不卡精品| 亚洲av无码专区在线亚| 99热国产这里只有精品9| 国产成人综合在线观看不卡| 永久国产盗摄一区二区色欲| 亚洲丰满熟女一区二区蜜桃| 国产L精品国产亚洲区在线观看| 成人性生交片无码免费看| 国产成人综合95精品视频| 久久一日本道色综合久久| 强奷乱码中文字幕| 国产尤物精品自在拍视频首页| 久久精品国产字幕高潮| 日韩有码中文在线观看| 久久精品一偷一偷国产| 中文字幕日韩精品有码| 国产成人无码精品久久久露脸| 亚洲一区二区av偷偷| 亚洲天堂精品一区二区| 日韩有码中文在线观看| 亚洲大尺度无码专区尤物| 成人国产精品中文字幕| 水蜜桃视频在线观看免费18| 久久天天躁夜夜躁狠狠| 老妇女性较大毛片| 久热这里只有精品12| 亚洲中文字幕一区二区| 欧美性猛交xxxx黑人猛交| 国产精品一码二码三码| 国产日韩综合av在线|