【问题标题】:C#/COM interop working only in debuggerC#/COM 互操作仅在调试器中工作
【发布时间】: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。我有源代码,但目前没有合适的构建环境。即使我这样做了,我也不确定如何从托管代码中调试它。这可能吗?]

更新

尚无解决方案,但还有一些观察:

  1. 我尝试以管理员身份运行该应用程序,并且还关闭了 UAC。结果相同。
  2. 我尝试在错误发生之前附加到进程,但在输出窗口中没有看到抛出结构化异常的指示。
  3. 我尝试将测试应用程序的主线程的公寓模型显式设置为 STA,然后是 MTA,但这没有任何区别。 COM 组件是单元线程的。
  4. 我尝试在 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 捕获。

标签: c# com interop


【解决方案1】:

您是否可能正在运行 AnyCPU 构建,并且出于某种原因,Visual Studio 将程序集加载为 32 位,但是当您在 VS 之外运行程序时,它以 x64 运行,因此无法加载 32 位 COM dll?

【讨论】:

  • 感谢您的建议。我在 64 位机器上运行 32 位窗口。我将目标从 AnyCPU 更改为 x86,但没有任何区别。
【解决方案2】:

我遇到了同样类型的问题。在我的情况下,强制 .NET 应用程序为 32 位并制作

    [STAThread]
    public static int Main(string [] args)

或(用于线程)

   thread = new Thread(DoWorkUsingCOM);
   thread.SetApartmentState(ApartmentState.STA);
   thread.Start();

解决了问题。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 2010-12-14
    • 2011-02-25
    • 2012-06-09
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多