如何在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
接口的对象。
我无法使用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。全部来自命令行。