C# 如何从托管代码调试未发布的COM引用?

C# 如何从托管代码调试未发布的COM引用?,c#,.net,debugging,com,clr,C#,.net,Debugging,Com,Clr,我一直在寻找一种工具来调试未发布的COM引用,这通常会导致Word/Outlook进程挂起在内存中,以防代码无法在所有COM实例上正确调用Marshal.ReleaseCOMObject。(Outlook 2007部分修复了Outlook加载项的问题,但这是一个一般性问题) 是否有一个工具可以至少显示托管代码持有的COM引用列表(按类型)?理想情况下,它还将显示内存探查器样式的对象树,帮助调试发生引用增量的位置 运行时调试并没有能够连接到挂起的进程那么重要——因为问题通常发生在使用COM接口完成

我一直在寻找一种工具来调试未发布的COM引用,这通常会导致Word/Outlook进程挂起在内存中,以防代码无法在所有COM实例上正确调用
Marshal.ReleaseCOMObject
。(Outlook 2007部分修复了Outlook加载项的问题,但这是一个一般性问题)

是否有一个工具可以至少显示托管代码持有的COM引用列表(按类型)?理想情况下,它还将显示内存探查器样式的对象树,帮助调试发生引用增量的位置

运行时调试并没有能够连接到挂起的进程那么重要——因为问题通常发生在使用COM接口完成代码时,而有人忘记发布某些内容时——即使在调用托管应用程序退出后,应用程序(例如winword)仍挂起在内存中


如果不存在此类工具,原因(技术?)是什么?在使用COM interop时,它对于调试许多其他方面很难发现的问题非常有用。

不是您要寻找的答案(或简单到),但是ReleaseCOMObject(与它包装的本机版本一样)返回一个整数,该整数应指示剩余的未完成引用数。您可以向项目中添加代码来显式执行AddRef,这样您就可以发布,并查看新的计数,以及它是否符合您的预期,等等。

下面是我使用调试器调试COM引用的答案


如果挂起的原因是使用枚举器,或者忘记“train”属性访问需要释放每个实例,例如document.Sections[0].Ranges[0].Text,则根本无济于事。我承认,挂起的原因并不像您所寻找的那样干净或简单。但是,如果您创建了一个AddRef和Release子例程,并报告返回值,并在使用对象之前和之后调用它(或者仅在您怀疑的对象之前和之后调用它,以减少工作量),您将更好地了解正在发生的事情。例如,如果您在使用枚举器之前和之后都这样做,您可以看到代码中是否有东西留下了引用。