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

本文关键字:COM 对象 接口 查询 动态 | 更新日期: 2023-09-27 18:26:34

我喜欢使用dynamic变量访问COM对象。然而,我有一个对象有问题。请参阅以下在VBS中工作的代码:

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

itg是一个特定的对象,它在vbscript和c#中使用动态变量基本上都能很好地工作。直到我尝试使用成员FirmaInfo。看起来它是一个非常特殊的成员,需要QueryInterface调用。当我通过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

我在c#中找不到这样做的方法。当我做一个简单的方法:

Console.WriteLine(itg.FirmaInfo.Nazwa)

我得到一个错误:

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

我知道我可以尝试一个静态客户端到COM对象,但我不熟悉这种技术。也许我可以继续使用我的动态方法,但只需要3行合适的代码?将我的FirmaInfo对象转换为公开IFirmaInfo接口的对象。

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

我无法使用dynamic完成任务。我提出了一个变通办法。

将自己切换到访问COM对象的静态方式变得非常简单快捷。花了几分钟。以下是我所做的:

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

这些命令生成一个DLL。我使用ilspy分析DLL,但ildasm也可以。我需要在代码中使用确切的名称。最后,在添加了对tlbimp创建的dll的引用后,我可以将唯一失败的调用更改为静态强制转换。

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

所以事情开始工作了,我可以继续前进了。我不使用GUI。全部来自命令行。