4

全部:

我在将一些 VBA 代码转换为 C# 时遇到了一些问题。

我们有一个充当本地 COM 服务器的 3rd 方应用程序。

在 VBA 代码中,我们使用GetObject()来获取对现有对象的引用

例如

Set appHandle = GetObject("", ProgId)

这很好用。

我在我们的 c# 代码中添加了对 3rd 方应用程序的引用,并使用 Marshal.GetActiveObject()尝试获取对正在运行的实例的引用。

例如

var appModel = (IAppCoModel)Marshal.GetActiveObject(ProgId);

但我不断收到MK_E_UNAVAILABLE错误。

在 C# 代码中创建新对象可以正常工作

例如

var appModel = new AppCoModel()

这将启动 3rd 方应用程序并允许我与之通信。它只是获取对失败的正在运行的实例的引用。

我试过的

不同的安全上下文
VS 在管理员模式下运行,第 3 方应用程序不是。我尝试从命令行(非管理员)运行我们的 c# 应用程序。仍然失败。

检查 ROT 内容
(由Marshal.GetActiveObject() 建议在 C# 中引发 MK_E_UNAVAILABLE 异常
3rd 方应用程序未出现在其中。不知道足够的 COM 以确保它需要。

检查所有注册表条目
看起来不错(据我所知),它们足以创建和实例化 3rd 方应用程序并让 VBA 找到它。我应该在这里检查什么具体的东西?

人们可以提出的任何建议将不胜感激。

4

1 回答 1

6

全部:

不太清楚结束自己的问题的礼仪是什么,但既然我找到了答案,我想以某种方式将其标记为“不需要答案”

GetActiveObject() 返回 MK_E_UNAVAILABLE 的原因是第 3 方应用程序未注册为自动化服务器。无法获得对正在运行的实例的引用。

这没有在 VBA 代码中显示,因为:

  1. GetObject("",ProgID)每次创建一个新实例(http://msdn.microsoft.com/en-us/library/gg251785.aspx

  2. 3rd 方应用程序中的 COM 公开功能会在应用程序未运行时启动该应用程序。因此,在 VBA 中,我们创建了多个对象,它们都指向同一个正在运行的应用程序,而不是附加到正在运行的应用程序。

于 2012-04-13T13:20:42.540 回答