如何添加对远程COM +应用程序的类型调用的支持

时间:2014-07-03 15:10:31

标签: c# .net com

我正在使用.Net变体替换COM +托管应用程序。

我采取的步骤大致是:

  • 生成旧dll的Interop程序集
  • 在C#.Net中创建一个新类,该类派生自ServicedComponent并从互操作实现IMyClass接口。
  • 我用[Guid(" ...")]和[ProgId(" ...")]属性注释了该类,以匹配该类老dll

最终结果如下:

[ProgId("MyComponent")]
[Guid("...")]
public class MyClass : ServicedComponent, IMyClass
{

    public MyClass()
    {

    }

    public object Open(string arg1, string arg2)
    {
        /* trace arguments*/
    }

    public object Run()
    { 
        /* implementation here */ 
    }

    public void Close()
    {
        return;
    }
}

使用regsvcs.exe

将此程序集安装在远程计算机上

现在大多数客户使用类似于此单元测试代码的代码:

Type typeFromProgID = Type.GetTypeFromProgID("MyComponent", "remoteMachine", true);
dynamic comInstance = Activator.CreateInstance(typeFromProgID);
comInstance.Open(string.Empty, string.Empty);
comInstance.Run();
comInstance.Close();

这很好用,远程机器上的.Net跟踪告诉我一切正常。其他客户端使用与此类似的代码:

Type typeFromProgID = Type.GetTypeFromProgID("MyComponent", "remoteMachine", true);
MyClass comInstance = (MyClass)Activator.CreateInstance(typeFromProgID);
comInstance.Open(string.Empty, string.Empty);
comInstance.Run();
comInstance.Close();

第一行是相同的,似乎工作正常,其余的行为很奇怪。 VS调试器显示正在执行的行。 remoteMachine显示没有正在执行的方法。

对Close()的最后一次调用实际上只是返回,抛出异常:

  

System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。   结果StackTrace:   在Interop.MyComponent.IMyClass.Close()     在UnitTestProject1.UnitTest1.temp()

我在实施中错过了什么来支持最后一个(打字的)场景?

1 个答案:

答案 0 :(得分:1)

这听起来像是不匹配的元数据,例如编组与原始类型库之间的编组和服务器注册的.NET程序集之间的编组不同。

我的猜测是,无类型的情况运行良好,因为它完全依赖于IDispatch,.NET实现得很好,但是由于这种不匹配,键入的测试失败了(我很惊讶它没有先前失败)。 / p>