简体   繁体   English

我如何在我使用RegistrationServices注册的C#中调用COM对象

[英]How do I call a COM object in C# that I registered using RegistrationServices

I'm experimenting with COM objects and created a simple COM service that acts as a calculator with add, subtract, multiply, divide (details not important). 我正在尝试使用COM对象,并创建了一个简单的COM服务,该服务充当具有加,减,乘,除的计算器(细节并不重要)。

I then wrote some code to register it dynamically with a C# application 然后,我编写了一些代码以在C#应用程序中动态注册它

Assembly asm = Assembly.LoadFile("C:\\...COMCalc.dll");
RegistrationServices regAsm = new RegistrationServices();
bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);

After registering it I've been able to use the service from an IE browser in javascript. 注册后,我已经可以使用javascript在IE浏览器中使用该服务。

var num1 = 2
var num2 = 2
var objTest = new ActiveXObject("COMCalc.COMCalc")
alert(num1 + " - " + num2 + " = " + objTest.Subtract(num1,num2))

I'd like to now be able to test it from my C# Application so I can have a register, unregister, and test method for my COM object. 我现在希望能够从C#应用程序中对其进行测试,以便为COM对象提供注册,注销和测试方法。 I've struggled to find the documentation for how to do this. 我一直在寻找如何执行此操作的文档。 Any Ideas? 有任何想法吗?

Bonus: I also would like to access it with the GUID defined in the COM object as opposed to the COMCalc. 奖励:我也想使用COM对象中定义的GUID(而不是COMCalc)来访问它。

   regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase)

By writing your own custom registration method, you are missing out on the normal way that COM client programs or unit testers will exercise your code. 通过编写自己的自定义注册方法,您会错过COM客户端程序或单元测试人员执行您的代码的常规方法。 They'll use the type library of your COM component, a machine-readable file that describes the types that you expose from your component. 他们将使用COM组件的类型库,这是一种机器可读的文件,用于描述您从组件公开的类型。 It is the COM equivalent of .NET metadata. 它与.NET元数据在COM中等效。

You get a type library by using the normal way to register, either by using your project's "Register for COM Interop" setting or by running Regasm.exe with the /tlb option. 通过使用普通的注册方法(通过使用项目的“注册COM Interop”设置)或通过运行带有/ tlb选项的Regasm.exe,可以获得类型库。 Or by running Tlbexp.exe to generate it manually. 或通过运行Tlbexp.exe手动生成它。

This however does not let you test your component with a C# unit test, you'd normally use Project > Add Reference > Browse and pick the .tlb file. 但是,这不允许您使用C#单元测试来测试组件,通常使用“项目”>“添加引用”>“浏览”并选择.tlb文件。 But the IDE refuses to accept it, it can see that the type library was created from a .NET assembly. 但是IDE拒绝接受它,它可以看到类型库是从.NET程序集创建的。 It insists that you use a normal assembly reference instead, picking the DLL instead. 它坚持要求您改用普通程序集引用,而是选择DLL。

There's a very good reason for that. 有一个很好的理由。 You can fool the IDE by using late binding but that does not fool the CLR. 您可以使用后期绑定来欺骗IDE,但这不能欺骗CLR。 In other words, you are not actually testing the COM interop at all. 换句话说,您实际上根本没有测试COM互操作。 You might as well use the normal way to add a .NET assembly reference. 您也可以使用常规方法添加.NET程序集引用。 Truly testing the component requires using a COM client written in a non-.NET language. 要真正测试组件,需要使用以非.NET语言编写的COM客户端。 Not that many practical ones around anymore, you could use a scripting language like Javascript or VBScript. 现在已经没有太多实用的代码了,您可以使用Javascript或VBScript之类的脚本语言。 The closer it is to the actual language and runtime environment that is going to use your component, the better. 它与将要使用组件的实际语言和运行时环境越接近越好。 If you are going to use it in a browser then something like Selenium or HtmlAgilityPack would be wise choice. 如果要在浏览器中使用它,那么明智的选择是Selenium或HtmlAgilityPack。

Nobody ever likes to hear advice like that. 没有人喜欢听到这样的建议。 You fool the IDE by late binding, very similar to what you did in the browser: 您可以通过后期绑定来欺骗IDE,这与您在浏览器中所做的非常相似:

Type type = Type.GetTypeFromProgID("COMCalc.COMCalc");
dynamic obj = Activator.CreateInstance(type);
dynamic result = obj.Subtract(2, 1);

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

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