简体   繁体   English

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

[英]How do I add support for typed calls to a remote COM+ application

I am in the process of replacing a COM+ hosted application with a .Net variant. 我正在用.Net变体替换COM +托管的应用程序。

The steps I took are roughly: 我采取的步骤大致是:

  • Generate an Interop assembly of the old dll 生成旧dll的Interop程序集
  • Create a new class in C# .Net that derives from ServicedComponent and implements the IMyClass interface from the interop. 在C#.Net中创建一个新类,该类派生自ServicedComponent并从互操作实现IMyClass接口。
  • I have annotated the class with a [Guid("...")] and a [ProgId("...")] attribute to match the class in the old dll 我用[Guid(“ ...”)]和[ProgId(“ ...”)]属性注释了该类,以匹配旧dll中的类

The end result looks like this: 最终结果如下所示:

[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;
    }
}

This assembly is installed on a remote machine using regsvcs.exe 使用regsvcs.exe将该程序集安装在远程计算机上

Now most clients use code similar to this unittest code: 现在,大多数客户端使用的代码与此单元测试代码相似:

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

This works perfectly, the .Net tracing on the remote machine tells me everything is working as it should. 完美运行,远程计算机上的.Net跟踪告诉我一切都在正常进行。 Other clients use code similar to this: 其他客户端使用类似于以下代码:

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

The first line is the same and seems to work fine, the rest acts weird. 第一行是相同的,似乎工作正常,其余行的行为很奇怪。 The VS debugger shows the lines are being executed. VS调试器显示正在执行的行。 The remoteMachine shows that no methods are being executed. remoteMachine显示未执行任何方法。

The last call to Close(), which actually just returns, throws an exception: 实际上刚刚返回的对Close()的最后一次调用将引发异常:

System.AccessViolationException: Attempted to read or write protected memory. System.AccessViolationException:尝试读取或写入受保护的内存。 This is often an indication that other memory is corrupt. 这通常表明其他内存已损坏。 Result StackTrace: at Interop.MyComponent.IMyClass.Close() at UnitTestProject1.UnitTest1.temp() 结果StackTrace:位于UnitopProject1.UnitTest1.temp()的Interop.MyComponent.IMyClass.Close()处

What have I missed in my implementation to support this last (typed) scenario? 我在实现过程中错过了什么来支持最后一种(类型化)场景?

This sounds like mismatched metadata, eg marshaling is different between the one that happens with the original type library and the one that happens with your server registered .NET assembly. 这听起来像元数据不匹配,例如,在原始类型库中发生的编组与在服务器注册的.NET程序集中发生的编组有所不同。

My guess is that the untyped case runs well because it depends solely on IDispatch, which .NET implements quite well, but the typed test fails (and I'm surprised it doesn't fail earlier) because of this mismatch. 我的猜测是,无类型的情况运行良好,因为它仅取决于IDispatch,.NET实现得很好,但是由于这种不匹配,有类型的测试失败了(我很惊讶它没有更早失败)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM