将 COM 对象同化到 C#“动态”变量时出现意外错误

Unexpected error when assiging COM object to a C# 'dynamic' variable

提问人:JBL 提问时间:11/17/2023 更新时间:11/17/2023 访问量:36

问:

我对 C# dynamic 关键字提供的可能性很感兴趣,但我遇到了意想不到的问题。

如果我在 Visual Studio 2022 中创建默认的 .NET 4.8 模板...

这工作原理:

dynamic obj = Marshal.GetActiveObject("Excel.Application");
obj.Workbooks.Add();

这也有效:

object obj1 = Marshal.GetActiveObject("FancySoft.Application");
object obj2 = obj1.GetType().InvokeMember("FancyProperty", BindingFlags.GetProperty, null, obj1, null);

此操作失败,并显示:System.Runtime.InteropServices.COMException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'

dynamic obj1 = Marshal.GetActiveObject("FancySoft.Application");
object obj2 = obj1.FancyProperty;

最后,如果我将对 FancySoft 的 COM 引用添加到我的项目中,这将按预期工作:

var obj1 = (Application) Marshal.GetActiveObject("FancySoft.Application");
var obj2 = obj1.FancyProperty;

我发现了一个有趣的讨论线程,它建议供应商可以有意限制在客户端应用程序中使用动态关键字。

就我而言,供应商甚至没有正式支持 .基于 NET 的自动化方案(尽管这是我们行业中的常见方案),所以我不能向他们询问此类信息。

你在其他地方看到过这种行为吗? 我错过了什么吗? 有没有办法在不询问供应商的情况下确认这种行为是故意的?(通过查看 .TLB文件,使用一些反射技巧等?

C# 动态 COM

评论

0赞 Hamlet Hakobyan 11/17/2023
这是处理您的问题的综合文档。learn.microsoft.com/en-us/dotnet/framework/interop/......
1赞 Simon Mourier 11/17/2023
dynamic大多数(不完全)使用(“aka late binding”,这是基于名称的),是的,这完全有可能不起作用。我怀疑这是故意的,更像是一个糟糕的界面设计,正如其他帖子 stackoverflow.com/questions/77478817/ 所展示的那样......IDispatch
0赞 JBL 11/17/2023
@SimonMourier我今晚写了一个最小的 vbscript,它与另一篇文章中的 Name 属性按预期工作。那也应该使用 IDispatch,对吧?如果是这样,为什么会有不同的行为?
1赞 Simon Mourier 11/17/2023
vbscript 内部结构与 .net 内部结构不同,有很多方法可以使用 IDispatch。很难说更多,没有一个复制 COM 对象来测试我自己测试这个特定的 IDispatch
0赞 JBL 11/17/2023
谢谢@SimonMourier,我从每个答案中学到了很多东西。不幸的是,您极不可能访问此程序。我刚刚在 VB.NET 项目中尝试了相同的示例,并且可以按预期访问该属性(无论 obj1 是定义为对象还是应用程序)。我本来以为 VB 中的行为会更接近 C#,但事实显然并非如此。

答: 暂无答案