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

时间:2015-12-11 11:13:33

标签: c# activex

我喜欢使用dynamic变量来访问COM对象。但是我有一个对象的问题。请参阅以下在VBS中使用的代码:

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

itg是一个特定的对象,在vbscript和c#中使用动态变量基本上同样有效。直到我尝试使用成员FirmaInfo。看起来它是一个非常特殊的成员,需要QueryInterface电话。当我通过雅各布访问它时,就是这样:

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接口的对象的东西。

1 个答案:

答案 0 :(得分:0)

我无法使用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。全部来自命令行。