【问题标题】:Export a method alias of COM visible .NET class导出 COM 可见 .NET 类的方法别名
【发布时间】:2019-04-04 11:55:34
【问题描述】:

我有一些实用程序的 .NET 实现结构和一个实例化 .NET 对象的 .WSC 脚本。目标是消除WSCscript 并直接实例化和调用.NET 实现。但这发现了一个命名问题。

WSC 中定义的类包含几个方法。其中一种方法是Finalize()。函数名称在 .NET 中保留,因为它用于生命周期和 GC 管理。因此,WSC 调用了一个不同名称的 .NET 函数:

<?xml version="1.0"?>
<component>
  <public>
    <method name="Finalize"/>
  </public>
  <object id="wrapper" progid="JS.Wrapper"/>

  <script language="JScript">
    <![CDATA[
      // Processes last required steps and closes all logs
      function Finalize() {
         return wrapper.Finish();
      }
      // Any other function
      function Foo() {
        wrapper.Foo();
      }
    ]]>
  </script>
</component>

.NET 类实现Finish 函数:

[ComVisible(true)]
[ProgId("JS.Wrapper")]
public class MyCom
{
    // Processes last required steps and closes all logs
    public void Finish()
    {
    }

    public void Foo()
    {
    }
}

有数以千计的脚本调用所有的 Foo() 和 Bar() 函数。而且它们中的大多数还调用Finalize 函数。因此无法在 COM 接口更改函数名。

  • 如何使用名称 Finalize 使函数 Finish 成为 COM 可见的?
  • 有没有办法实现两个 Finalize 函数,一个用于 .NET 运行时,一个在 COM 接口处导出。
  • 是否可以显式实现 COM 接口,即自定义实现 COM 接口?

有一个属性ComAliasName 可用于使属性、索引器、字段、参数或返回可见的别名。但它不能用于方法名称。如何将方法显示为别名?

【问题讨论】:

  • 您可以调用 C# 方法 finalize 全部小写(例如),这样它就不会干扰终结器。底层 IDispatch 实现(允许您从脚本客户端使用 C# COM 对象)无论如何都不区分大小写。推论问题:为什么需要 .NET COM 对象的终结器?
  • @SimonMourier 抱歉,我不完全理解您的评论。哪个模块应该调用finalize?什么情况下应该这样做?
  • 您可以在 MyCom 类中命名(不调用,抱歉)方法 finalize 而不是 Finish
  • @SimonMourier 我对 COM 可见界面的区分大小写有不同的体验。如果调用脚本调用了foo方法,而.NET类实现了Foo,则报错:“Object doesn't support this property or method' 0x800A01B6. 如果.NET类实现了finalize方法,脚本中Finalize的调用如何调用finalize方法。
  • 奇怪。这是 myproject 可以正常工作的地方:1drv.ms/u/s!AsmmEDGvydk2lCpnt3Lop93BCA8K 你能测试一下吗?

标签: .net com comvisible


【解决方案1】:

Finalize 方法可以通过显式定义 COM 接口来公开。

public interface IMyCom
{
    // Processes last required steps and closes all logs
    void Finalize();
    void Foo();
}

在实现 .NET 类中选择 ClassInterfaceType.None 很重要。 .NET 类中的实现应指定实现的接口。使用范围前缀IMyCom,编译器可以区分COM 接口上的方法名称和一些.NET CLR 内部名称。这使得无需使用不同的方法名称并创建别名。

[ComVisible(true)]
[ProgId("JS.Wrapper")]
[ClassInterface(ClassInterfaceType.None)]
public class MyCom : IMyCom
{
    // Explicitly specify the scope of the Finalize method.
    void IMyCom.Finalize()
    {
    }

    void IMyCom.Foo()
    {
    }
}

这种方法也清楚地表明这是一个 COM 接口方法的实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多