Asp.net

使用 4.0 框架和 Visual Studio 2010 為 ASP Classic 建構 COM 互操作庫

  • December 1, 2016

在瀏覽了許多不同的文章並且沒有發現任何特別有說服力的東西可以讓我逐步完成整個過程之後,我來尋求幫助。

情景

我的一個客戶只精通ASP Classic的開發。他們最近獲得了一個最初用 ASP.NET 編寫的網站的帳戶。他們正在將站點滾動到可以主動維護的位置,但該站點最初包含一個圖像處理程序,該處理程序獲取有關水位的動態變化數據並輸出包含該數據的圖形表示的圖像。要求是開發一個COM互操作庫,可以在伺服器上註冊並使用 CreateObject 呼叫以使用Response.BinaryWrite生成相同圖像的字節數組用於輸出. COM 互操作庫必須在 Windows 2000 Server 上的遠端站點上註冊,我無法假設他們可以訪問 regasm/gacutil 來完成該任務。

困難

我通過在 Visual Studio 2010 中創建一個類庫項目,從模板中選擇“COM 類”,並插入我的程式碼以生成一個具有單個公共方法的類,從而在給定整數時返回一個字節數組(好吧,列舉器,但都一樣)。不幸的是,即使在建構庫並註冊(regasm)和記憶體程序集(gacutil)之後在我自己的開發機器上,我也無法通過 Classic ASP 進行呼叫來實例化對象,而是接收到“ ActiveX組件無法創建對象”錯誤。而且,當然,在伺服器站點,無法註冊 DLL 文件,響應是“找不到所需的模組”。

我用過的資源

我已經瀏覽了以下文章,但還沒有找到我需要的答案:

  1. (基本步驟)演練:使用 Visual Basic 創建 COM 對象
  2. 建構和部署 .NET COM 程序集
  3. 帶有經典 ASP 的 .NET COM+ 互操作組件

我需要的

本質上,我需要的是一點點掌握在 Visual Studio 2010 中滿足要求並正確創建COM+互操作模組所需要採取的步驟。創建實際的類對象本身並不可怕難的。

但是,我瀏覽過的文章都沒有真正討論項目選項或使用 Visual Studio 2010 或 .NET 4.0 Framework 建構過程,也沒有真正討論過部署到 Windows Server 2000 等舊系統時是否有特殊考慮以及庫在系統上的實際註冊,例如,手頭只有regsvr32 。

將基本的 .NET 程序集暴露給 COM 應該相當簡單——我從未嘗試過 COM 類項目模板,所以這是我過去管理它的方式:

使用 C# 或 VB 創建一個新的(沼澤標準).NET 類庫。定義一個 COM 介面(用您自己的 GUID 替換):

[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
   string GetMyGroups();
}

現在定義一個實現該介面的類(同樣,用您自己的 GUID 替換):

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
   public string GetMyGroups()
   {
       var comm = new CommunicatorAPI.MessengerClass();

       var groups = comm.MyGroups as IMessengerGroups;
       return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
   }
}

此類的 Prog ID 屬性將用於從 ASP 實例化您的組件。

強命名程序集(項目屬性->“簽名”選項卡->“簽署程序集”->使用下拉列表創建新的強名稱密鑰文件)

現在,建構程序集,並使用Regasm註冊- 如果您不想在 GAC 中註冊(我建議您這樣做,因為 GACing 不會使部署更簡單),請務必使用 -Codebase 參數(這只是添加一個 reg 條目,告訴客戶在哪裡可以找到程序集) - 例如:

regasm ClassLibrary2.dll /codebase "S:\Testing\ClassLibrary2\ClassLibrary2\bin\Debug\ClassLibrary2.dll"

現在您應該能夠實例化組件,並在其上呼叫方法 - 例如(在 javascript 中):

var a = new ActiveXObject("Test.Comm.1");
alert(a.GetMyGroups());

在部署方面,Regasm 和 Regsvr32 做的重要工作就是將各種設置寫入系統資料庫,以便客戶端可以找到 COM 組件(基於 Prog ID,或 COM Class ID)。當您在本地機器上執行 Regasm 時,您需要做的就是計算出正在寫入的 COM 設置,並將這些設置寫入伺服器上的系統資料庫。您可以使用ProcMon來監視 Regasm 執行時寫入系統資料庫的內容。

一般來說,您可以期望看到這樣的內容寫入系統資料庫:

[HKEY_CLASSES_ROOT\Test.Comm.1]
@="ClassLibrary2.Comm"

[HKEY_CLASSES_ROOT\Test.Comm.1\CLSID]
@="{00585504-90C8-4760-A359-67CAF08FFED1}"

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}]
@="ClassLibrary2.Comm"

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories]

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32\1.0.0.0]
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\ProgId]
@="Test.Comm.1"

希望這可以幫助 :)

引用自:https://stackoverflow.com/questions/4923350