Tag: rcw

如何让LINQPad转到Dump()系统.__ ComObject引用?

我正在使用LINQPad来快速开发小型ArcObjects (一个基于COM的ESRI ArcGIS软件库)应用程序,并且已经成功地将它用于Dump()我从.NET初始化的COM对象的属性,但是从现有COM对象获取的COM对象只是作为System.__ComObject引用转储,这不是特别有用: 这个帮助主题解释了为什么会发生这种情况,我认为我理解,但是想知道解决这种行为有哪些选择,特别是在使LINQPad(甚至)更强大的环境中。 有趣的是,Visual Studio的调试器能够显示这些对象的属性,甚至是值类型的值: Visual Studio使用什么机制来实现这种内省,为什么LINQPad的Dump方法不会这样做呢? 编辑:请参阅有关VS如何执行此操作的相关问题: Visual Studio的调试器/交互式窗口如何在.NET中转储COM对象的属性? ArcObjects .NET SDK包含带有RCW的PIA,每个CoClass可以通过COM接口实现,所以我认为应该可以以编程方式包装这些对象。 作为一种解决方法,我在LINQ查询中成功使用Marshal.CreateWrapperOfType()来强制LINQPad在我碰巧知道应该使用哪个CoClass时转储对象的属性。 当然,这只能正确转储值类型属性 – 任何基于COM的引用类型属性仍然报告为System.__ComObject ,因此正确的解决方案必须以递归方式工作以获取那些包装。 在之前的一个问题中,我了解到CoClass可以在运行时确定它是否实现了IPersist ,这是ArcObjects的很大一部分。 我可以以某种方式使用这种技术或其他技术自动将System.__ComObject从PIA System.__ComObject为适当的RCW吗? 如果是这样,我如何在LINQPad中实现它,例如通过提供ICustomMemberProvider实现? 这可以是递归的,这样也可以包装也是COM对象的属性吗? 我正在使用面向.NET 4.0的LINQPad 4.x,但我也对支持LINQPad 2.x感兴趣(因此,首选适用于.NET 3.5和.NET 4.0的解决方案,但这不是必需的)。 更新:我已经弄清楚我的问题的第一部分是如何使用IPersist.GetClassID返回的CLSID在其RCW中包装System.__ComObject 。 请参阅此相关问题和我正在使用的代码的答案 。 我仍然想知道如何将其用于LINQPad的Dump方法。

C#包装器接口错误:E_NOINTERFACE

我正在尝试为我拥有的COM对象(名为SC_COM.dll)生成一个C#包装器,但是在将它与Visual Studio 2008(运行Vista)链接时遇到了一些问题。 我需要使用COM DLL免费注册 – 我使用清单文件让Visual Studio了解SC_COM.dll,这似乎有效。 我使用TblImp.exe生成我在Visual Studio 2008中引用的类型库(SC_COMtlb.dll),因此我可以使用我需要的DLL进行早期绑定。 DLL与清单和可执行文件位于同一目录中。 这是问题:当我实例化对象并尝试在C#中调用其中一个方法时,它会抛出以下错误: 检测到错误:无法将类型为“SC_COMtlb.SCAccessObjClass”的COM对象强制转换为接口类型“SC_COMtlb.ISCUploader”。 此操作失败,因为对IID为“{C677308A-AC0F-427D-889A-47E5DC990138}”的接口的COM组件的QueryInterface调用由于以下错误而失败:不支持此类接口(HRESULTexception:0x80004002(E_NOINTERFACE)) 。 我不完全确定这个错误意味着什么 – 我已经对错误代码进行了搜索,而且它似乎是一个相对普遍的C#错误。 所以我要在这里以错误的方式链接COM对象,还是有一些其他重要的步骤我可能会丢失? 我应该注意到,我不完全确定我生成的类型库(S \ C_COMtlb.dll)如何知道实际COM DLL的位置,因为它没有在系统中注册 – 我认为它只是看起来相同目录。 这可能是问题,如果是这样,我怎样才能更好地将这两者联系起来?

在C#中使用COM互操作时的RCW和引用计数

我有一个使用Office互操作程序集的应用程序。 我知道运行时管理的“运行时可调用包装器(RCW)”。 但我不太确定引用计数如何增加。 MSDN说, RCW只保留对包装的COM对象的一个​​引用,而不管调用它的受管客户端的数量。 如果我理解正确,在以下示例中, using Microsoft.Office.Interop.Word; static void Foo(Application wrd) { /* …. */ } static void Main(string[] args) { var wrd = new Application(); Foo(wrd); /* …. */ } 我将实例wrd传递给另一个方法。 但这不会增加内部引用计数。 所以我想知道引用计数增加的场景是什么? 任何人都可以指出引用计数增加的情况吗? 另外我读了一些博客,说在使用COM对象编程时避免使用双点。 像wrd.ActiveDocument.ActiveWindow这样的东西。 作者声称编译器创建单独的变量来保存将增加引用计数器的值。 恕我直言,这是错误的,第一个例子certificate了这一点。 那是对的吗? 任何帮助都会很棒!