【发布时间】:2011-07-07 13:48:34
【问题描述】:
我遇到了从 C# 应用程序到 inproc COM 服务器组件的 COM 互操作问题。
我已将问题简化为一个简单的 c# 测试程序。它实例化服务器组件的互操作类,将字符串的值设置为实例上的属性,然后设置另一个字符串属性。我没有在编组方面做任何不寻常的事情。仅使用我添加对 COM 组件的引用时生成的互操作类。比如:
using MyLib; // Interop assy
// ...
MyComp comp = new MyComp();
comp.Prop1 = "abc";
comp.Prop2 = "xyz";
结果:
如果我在 VS 之外运行测试程序,那么当设置第二个属性时,我始终会收到一个带有
0x80010105(RPC_E_SERVERFAULT) 的 HRESULT 的 COMException。如果我在 Visual Studio 2005 中运行测试程序,那么它始终可以正常工作。
我在非托管 C++ 中编写了等效代码(没有 atl,只是简单的接口指针),这在 VS 内外都能正常工作。
我的问题:在调试器中运行时发生互操作的环境有什么不同,这可能解释了我所看到的情况?我假设E_RPC_SERVERFAULT 是由互操作编组器生成的,但为什么只在调试器中生成?关于如何进行此操作的任何建议?
[关于 com 组件我没有说太多,因为我的问题是关于我在调试器内外看到的不同行为。 com 组件经过了很好的测试,并且已经在生产环境中使用了 7 年以上(在服务器环境中每天有数千次调用),所以我对此非常有信心。它是一个 32 位的 dll。我有源代码,但目前没有合适的构建环境。即使我这样做了,我也不确定如何从托管代码中调试它。这可能吗?]
更新
尚无解决方案,但还有一些观察:
- 我尝试以管理员身份运行该应用程序,并且还关闭了 UAC。结果相同。
- 我尝试在错误发生之前附加到进程,但在输出窗口中没有看到抛出结构化异常的指示。
- 我尝试将测试应用程序的主线程的公寓模型显式设置为 STA,然后是 MTA,但这没有任何区别。 COM 组件是单元线程的。
- 我尝试在 Win2003 机器和不同的 Win7 pro 机器上运行托管测试应用程序(Visual Studio 外部)。它在两者上都能正常工作。
最后一项表明我的机器有问题,但我不确定是什么问题。
[环境是在 Win7 Pro 32 位和 Visual Studio 2005 Pro 上运行的 Framework 2.0。]
【问题讨论】:
-
您是否偶然以管理员身份运行 Visual Studio? UAC / 权限可能是一个问题
-
这是一个与进程外 COM 服务器密切相关的故障。这几乎没有解释的余地。没有调试器就没有桨。启动后尝试附加调试器。
-
@BrokenGlass 好主意。我以管理员身份运行 VS2005。不好,我知道,但我在Win7上。我现在在家,我的开发箱的 vpn 似乎已关闭,所以我将尝试在早上的管理命令窗口中运行测试。谢谢!
-
@Hans Passant 谢谢! com 组件肯定是 inproc(我写的)所以 RPC 错误也让我感到困惑。我可以将调试器附加到测试应用程序,但我不知道该怎么做。我可以调试互操作程序集,或者从它或编组器中获得任何有用的东西吗?
-
我看到使用 RPC 的唯一场景是调用因公寓类型不匹配而被编组。在 C++ 中很容易忽略,但由 CLR 强制执行。您必须希望 SEH 异常,这是 HRESULT 的常见原因。它将在“输出”窗口中可见,并且可以使用 Debug + Exceptions 捕获。