所有
我在将一些VBA代码转换为C#时遇到了一些问题。
我们有第三方应用程序,它充当本地COM服务器。
在VBA代码中,我们使用 GetObject()来获取对现有对象的引用
e.g。
Set appHandle = GetObject("", ProgId)
这很好。
我在c#代码中添加了对第三方应用的引用,并使用 Marshal.GetActiveObject()来尝试获取对正在运行的实例的引用。
e.g。
var appModel = (IAppCoModel)Marshal.GetActiveObject(ProgId);
但我一直收到 MK_E_UNAVAILABLE 错误。
在C#代码中创建新对象可以正常工作
e.g。
var appModel = new AppCoModel()
这将启动第三方应用程序并允许我与之通信。它只是抓取对正在运行的实例失败的引用。
我尝试了什么
不同的安全背景
VS正在管理模式下运行,而第三方应用则不是。我尝试从命令行运行我们的c#app(非管理员)。仍然失败。
检查ROT内容
(由Marshal.GetActiveObject() throws MK_E_UNAVAILABLE exception in C#建议)
第三方应用程序未出现在其中。不知道足够的COM以确保它需要。
检查了所有注册表项
看起来不错(据我所见),它们足以创建第三方应用程序和实例以及VBA找到它。我应该在这里查看具体的内容吗?
任何人们可以提出的建议都将受到赞赏。
答案 0 :(得分:6)
所有
不太确定关闭自己问题的礼仪是什么,但是因为我找到答案我想以某种方式将其标记为'不需要答案'。
GetActiveObject()返回MK_E_UNAVAILABLE的原因是第三方应用程序未注册为自动化服务器。无法获得对正在运行的实例的引用。
这在VBA代码中没有显示,因为:
GetObject("",ProgID)
每次都会创建一个新实例(http://msdn.microsoft.com/en-us/library/gg251785.aspx)
如果应用未运行,第三方应用中的COM公开功能会启动该应用。因此,在VBA中,我们创建的多个对象都指向同一个正在运行的应用程序,而不是附加到正在运行的应用程序。