问题标签 [rcw]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
47 浏览

c# - 如何引用已编辑的互操作程序集

我一直在研究 C# 中的枚举 Windows 便携式设备,其中包括编辑为 PortableDeviceApi COM 对象生成的运行时可调用包装器 (RCW),因为默认的 COM 类型库导入过程导致该GetDevices方法的编组错误。因此,我遵循了如何:编辑互操作程序集来编辑 RCW,甚至设法建立一个 VS 项目以将其检入源代码并在构建期间按照此处给出的建议生成编辑后的 ​​RCW -是否有编译 CIL 的示例Visual Studio 项目中的代码

但是,无论我是手动构建自定义 RCW 还是从 VS 项目构建,我都无法让 VS 引用 RCW。以下是“有效”的方法:如果我按照正常程序添加 COM 引用(右键单击项目 > 添加 > COM 引用...),然后选择 PortableDeviceApi,则会将一个COMReference元素添加到 .csproj:

并且在项目的 obj 文件夹下添加了自动生成的 Interop.PortableDeviceApiLib.dll RCW。我可以用我从上面提到的编辑过的 MSIL 生成的那个来手动替换这个 DLL,这似乎工作得很好——我得到了 COM 对象的智能感知,以及编辑过的编组更改。这种方法的缺点是我必须将编辑后的 ​​DLL 复制到通过添加 COM 引用生成的 DLL 上,这看起来很不稳定(并且对自动构建管道不太友好)。

我尝试过的另一件事是直接引用 MSIL 项目的输出 DLL。这确实构建成功,但无论出于何种原因,智能感知和对象浏览器都没有获取元数据,因此这不是一个很好的开发人员体验。

最后,如果我尝试将自定义 RCW 的版本信息更改为 v1.1(库存 RCW 为 1.0)并相应地更新上述COMReference.VersionMinor元素,MSBuild 会抱怨

底层 COM 组件本身已注册。然而,到目前为止,我还没有找到任何关于如何注册 RCW 的信息。

我想接下来我可能会尝试使用混合,使用 MSIL 项目生成自定义 DLL,并使用标准的添加 COM 引用过程来给我智能感知,并在某处放置自定义构建步骤以复制 MSIL 项目的自定义 RCW,其中COMReference元素会期待它。但在我承诺解决方案之前 -

有没有人成功让 Visual Studio 干净地识别对自定义运行时可调用包装 DLL 的引用?理想情况下,我希望在“添加 COM 引用”对话框中可以使用更新后的 RCW,但这不是绝对要求。

0 投票
0 回答
51 浏览

c# - .net interop System.Runtime.InteropServices.Marshal.InternalWrapIUnknownWithComObject 某些场合死锁

尝试在包装 C++ Com 对象的 C# 代码中使用 RCW 时,我们遇到了死锁。它在大多数情况下都有效,但有时我们会在主线程停止的地方出现死锁:

我们已经尝试调试它,但这真的很难。不知何故,有些东西阻塞了在托管和本机之间进行通信的线程,但我看不出是哪个。

调用 !eestack 为我提供了以下信息,但我看不到导致死锁的原因。这个线程正在调用 CleanupWrappersInCurrentCtxThread 这有点可疑,但我没有关于这一切在内部如何工作的详细信息:

终结器看起来不错:

COM 对象用于获取 Oracle DB 句柄,选择是在 C# 上完成的。我们可以看到预言机参与其中,但我们仍然不知道如何检查谁真正在阻止。

如果有人对我如何进行或知道 RCW 内部如何工作以及可能导致僵局的原因有任何想法,我将不胜感激。

现在,我们生成了一个调用 RCW 的线程,它似乎可以工作,但实际上不应该发生这种死锁。

** 编辑 02.10.21 ** 这就是我的解决方法的样子:

我用这个来称呼它……虽然我并不为此感到自豪。

但这暂时解决了阻塞问题。如果我尝试等待任务。它永远阻塞。

敲响任何铃铛?

谢谢。

0 投票
0 回答
38 浏览

debugging - 调试(编组的)RCW 代理会阻止 COM 服务器上的消息循环 - 为什么?

我有一个访问 Excel 应用程序对象的简单过程。它订阅一个事件,然后将调试器附加到自身。

该应用程序的整个源代码如下:

当调试器(例如 Visual Studio)启动时,它会冻结(所有线程)我的控制台应用程序。

我觉得令人费解的是,这也阻止了 Excel 中的消息循环,使 Excel 无响应。但是,Excel 中的消息循环仅在我订阅某些事件时才会被阻止,例如 WorkbookNewChart。哪个事件无关紧要,事件是否被触发也无关紧要。

我的问题是:

  • 为什么将调试器附加到此控制台应用程序会冻结 Excel 的消息循环,我可以做些什么来阻止它?
  • 我只是将 Excel 的行为视为一个黑匣子 - 是否有任何工具可以用来找出可能阻止 Excel 进程中的消息泵的原因?

Loaded[更新:在 WPF 窗口的事件处理程序中运行相同的三行代码具有相同的结果。]


背景- 为什么我对此感兴趣:

我正在 Excel 中制作一个可用于构建小型应用程序的 IDE。这些应用程序在自己的进程中运行,但通过Marshal.GetActiveObject. 我的 IDE 是一个在 Excel 进程中运行的 Excel 插件。我希望我的 IDE 能够调试我从 IDE 生成的运行器进程。启动应用程序时似乎一切正常,但在上述情况下我陷入僵局,调试器冻结运行器进程,然后阻止 excel 进程,这使我无法使用调试器。

调试器的屏幕截图

当然,我可以在另一个单独的进程中运行我的调试器/IDE,但从用户体验的角度来看,如果可能的话,我希望将其保留在 Excel 任务窗格中。