简体   繁体   English

如何动态查询C#中COM对象的接口?

[英]How to query interface of a COM object in C#, dynamically?

I love using dynamic variables for accessing COM objects. 我喜欢使用dynamic变量来访问COM对象。 However I have a problem with one object. 但是我有一个对象的问题。 See the following code working in VBS: 请参见以下在VBS中工作的代码:

WScript.Echo "Nazwa firmy: " & itg.FirmaInfo.Nazwa

itg is a specific object that works basically equally well in vbscript and in c# using dynamic variables. itg是一个特定的对象,使用动态变量在vbscript和c#中基本上可以很好地工作。 Until I try to use the member FirmaInfo . 直到我尝试使用成员FirmaInfo Seems like it is a very special member which requires QueryInterface call. 似乎它是一个非常特殊的成员,需要QueryInterface调用。 When I was accessing it through Jacob it was in this way: 当我通过Jacob访问它时,是这样的:

static final String sIFirmaInfo = "{3F707848-DC7D-4B37-A4C8-7270644020F7}";
ActiveXComponent fi0 = itg.getPropertyAsComponent("firmainfo");
fi = new ActiveXComponent(fi0.QueryInterface(sIFirmaInfo));
fi0.safeRelease();
// now I am able access Nazwa member of fi

I can't find a way to do this in c#. 我找不到在C#中执行此操作的方法。 When I do a simple approach: 当我做一个简单的方法时:

Console.WriteLine(itg.FirmaInfo.Nazwa)

I get an error: 我收到一个错误:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.__ComObject' does not contain a definition for 'Nazwa'
   at CallSite.Target(Closure , CallSite , ComObject )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at Itg.open(String sKatFirmy, String sUser, String sPass) in w:\introl\prozapbi\Itg.cs:line 100

I know I could try a static client to COM object, but I am not familiar with this technique. 我知道我可以尝试使用静态客户端访问COM对象,但是我对这种技术并不熟悉。 Maybe I can stay with my dynamic approach, but need just a 3 suitable lines of code? 也许我可以继续使用动态方法,但只需要3条合适的代码行? Something that would turn my FirmaInfo object to one that exposes the IFirmaInfo interface. 会使我的FirmaInfo对象变为暴露IFirmaInfo接口的对象。

I wasn't able to accomplish the task using dynamic . 我无法使用dynamic完成任务。 I present a workaround. 我提出一种解决方法。

Switching myself to a static way of accessing a COM object turned out to be very easy and fast. 事实证明,将自己切换为访问COM对象静态方式非常容易且快速。 It took a couple of minutes. 花了几分钟。 Here's what I did: 这是我所做的:

set tlbimp="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\TlbImp.exe"
%tlbimp% "C:\path_to_type_library\Mxfk2015_c.dll"

These commands produce a DLL. 这些命令产生一个DLL。 I analyzed the DLL using ilspy , but ildasm would do too. 我使用ilspy分析了DLL,但是ildasm也会这样做。 I needed exact names to use in code. 我需要确切的名称以在代码中使用。 Finally after adding a reference to the dll created by tlbimp , I could change the only invocation that was failing to a static cast. 最后,在添加对tlbimp创建的dll的引用之后,我可以将唯一失败的调用更改为静态tlbimp转换。

 dynamic itg = ...
 var fi = (MXDokFK.FirmaInfo)itg.FirmaInfo;

So the thing started working and I could move on. 这样事情开始起作用,我可以继续前进。 I don't use GUI. 我不使用GUI。 All from command line. 全部来自命令行。

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

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