Dot-Net

無法訪問 VBA 中的 COM 公開方法

  • February 22, 2021

我正在嘗試訪問 VBA 中的 COM 公開方法。

**問題:**我在 VBA 中看到了所有預設方法(如和) GetHashCode,但不是作為 COM 介面一部分且專門編寫為 COM 可見的方法(如下所示)。GetType``ToString``getStringValue()

設置詳情:

  • 視覺工作室 2008
  • 視窗 7 x64
  • 辦公室 2007
  • .NET 3.5

介面“IGetMyString.cs”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SimpleCOMAssembly
{
   [ComVisible(true), GuidAttribute("4153A1AC-ECE9-4f66-B56C-1DDEB6514D5D")]
   [InterfaceType(ComInterfaceType.InterfaceIsDual)]
   interface IGetMyString
   {
       [DispId(1)]
       string getStringValue();
   }
}

實施“GetMyString.cs”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace SimpleCOMAssembly
{
   [ComVisible(true), GuidAttribute("0A3D4D65-CF50-4020-BF13-77001F8AAABE")]
   [ProgId("SimpleCOMAssembly.GetMyString")]
   [ClassInterface(ClassInterfaceType.None)]
   public class GetMyString : IGetMyString
   {
       public GetMyString() { }

       [ComVisible(true), Description("Get my string")]
       public string getStringValue()
       {
           return "hello";
       }
   }
}

在 Build 屬性中,我選中了**“Make Assembly COM Visible”**(見下面的快照)

在此處輸入圖像描述

還要求 Visual Studio 2005 進行**“註冊 COM 互操作”**(參見下面的快照)

在此處輸入圖像描述

最後,作為建構後事件,我正在執行 regasm.exe 來註冊 .DLL 以及 .TLB 到系統資料庫,如下所示:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm /codebase "$(TargetPath)" /tlb:"$(TargetDir)$(TargetName).lib"

在 Excel 對象資源管理器視圖中,我啟用了 COM 伺服器(上面寫的 SimpleCOMAssembly),現在在對象資源管理器中它沒有列出 COM 介面方法(見下文) 在此處輸入圖像描述

有人可以幫助我知道我缺少什麼導致 COM 介面方法未在 VBA 中顯示嗎?

編輯 附加生成的 TLB 的 ITypeLib 視圖 在此處輸入圖像描述

Excel 對象瀏覽器螢幕截圖清楚地顯示了一個問題。請注意 GetHashcode、GetType 和 ToString 方法是如何可見的。這些是從 System.Object 繼承的方法。但是您的程式碼段明確(並且正確)使用

$$ ClassInterface(ClassInterfaceType.None) $$以便隱藏類實現。 它沒有隱藏。不太清楚這是怎麼發生的,早期嘗試的舊類型庫可以解釋它。但是您的建構步驟非常可疑,您提供的幫助太多了。“使程序集類型 COM 可見”選項是強制建構系統公開 .NET 類型的一種非常粗略的方法。但是您的程式碼正在使用精煉的右上角-pinky-up-when-you-drink-tea 方式向 COM 公開類型。其中包括

$$ ComVisible(true) $$屬性、複選框的作用以及$$ ClassInterface $$屬性,這是複選框不做的事情。 所以問題是你要求建構系統實現兩個介面。無論它從基類繼承什麼,在你的例子中是 _Object,加上它從聲明中繼承的,在你的例子中是 IMyGetString。這很好,並且與 COM 完全兼容,但 VBA 不是一個很好的 COM 使用者。它只喜歡

$$ Default $$介面,在你的情況下就是 _Object 。從截圖中清晰可見。 所以關閉“使程序集 COM 可見”選項。

並在呼叫 Regasm 的建構後事件或“註冊 COM 互操作”複選框之間進行選擇。兩種方式都這樣做只會使您不知道為什麼它不起作用的機率增加一倍。只有在需要為 64 位版本的 Office 註冊程序集時才需要 postbuild。

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