【问题标题】:How do I create a component that gives VBA access to my own running Application?如何创建一个组件,让 VBA 访问我自己正在运行的应用程序?
【发布时间】:2017-05-29 19:43:42
【问题描述】:

很抱歉,我根本不知道这里的术语。我不是在寻找一个完整的解决方案,只是在可能的情况下帮助了解要搜索的技术或教程。

我有一个 .NET 应用程序,我想授予 VBA 访问当前正在运行的应用程序实例的权限。换句话说,我想创建对我的应用程序的类似访问,就像 Microsoft 对正在运行的 Office Word 或 Excel 实例所做的那样。

我可以创建 VBA 可以使用的 COM 可见 .dll,但现在我希望它使用我当前正在运行的应用程序。

【问题讨论】:

  • 因为 VBA 不会成为编写此代码的内容。它将使用 .NET 编写,而我的首选是 VB.NET。我只是希望它 COM 可见,以便 VBA 可以使用它。
  • 我认为您的问题术语是如何为我的应用程序开发 IDE(如 vba 具有 vbe)。在谷歌上搜索,一无所获,并为该问题投票。我建议您添加更多标签(vb.net 标签 [遗憾] 没有太多浏览量)
  • 您建议使用哪些标签?我不确定我是否要创建一个 IDE。我想我想要的是向 ROT 注册我的应用程序的一个正在运行的实例,以便我可以“获取一个活动对象”我认为这被称为 moniker。
  • 似乎更像绰号,我建议添加c#,vba标签。
  • @darbid Ohhh gotcha。我之前也遇到过同样的问题,但是我不知道如何通过 COM 访问已经运行的应用程序;我什至不确定这是否可能,因为如果 COM 任何应用程序都可以连接到任何 COM 对象,这可能是一个巨大的安全漏洞。相反,我编写了一个基于套接字的通信协议。我会在本地运行一个服务器进程;每当应用程序启动时,它都会登录到本地服务器。然后,您可以编写一个 COM 可访问的 .NET 客户端。然后,在 VBA 中,您可以使用 COM 创建一个连接到服务器的新客户端,并通过它连接到您的应用程序。

标签: c# vb.net vba com


【解决方案1】:

您正在寻找在单独进程中运行的进程外 COM 服务器。这允许客户端附加到您的应用程序已经运行的实例。例如,查看this 教程。

【讨论】:

  • 感谢 Aurora - 我现在了解术语或搜索词“Out-of-Process Com Server”。但我仍然不确定附加到正在运行的实例。这在技术上叫什么?
  • 我不确定技术术语,但是它遵循这种模式:您将构建一个新的进程外 COM 服务器并将您的应用程序逻辑嵌入其中。完成注册步骤后,您可以通过运行应用程序 exe 并创建新实例来启动服务器。然后,VBA 客户端可以通过使用适当的类名调用 GetObject() 来附加到此实例。
  • 感谢极光。我想给你答案,但也会添加一些东西。
【解决方案2】:

我确实只要求提供我想要的术语,但我在 VB.NET 中找到的信息很少。

given above by Aurora from MS 示例是进程外 COM 服务器的示例,您只能在 VBA 中调用 CreateObject。您不能调用 getobject,因为此示例未将必要的信息添加到运行对象表 (ROT)。

这意味着如果你想访问一个已经在运行的应用程序,你不能使用这个例子。

要解决此问题,您需要在 VBSimpleObject 的实例上调用 RegisterActiveObject 以将您的类添加到 ROT。我在 VB.NET 中找不到可靠的 WinAPI 签名,所以这里是注册和撤销签名

 <DllImport("oleaut32.dll")> _
Public Shared Function RegisterActiveObject(<MarshalAs(UnmanagedType.IUnknown)> ByVal pUnk As Object, _
                                            ByRef rclsid As Guid, ByVal dwFlags As IntPtr, _
                                            <Out()> ByRef lpdwRegister As UInt32) As Integer
End Function

<DllImport("oleaut32.dll")> _
Public Shared Function RevokeActiveObject(ByVal dwRegister As UInt32, ByVal reserved As IntPtr) As Integer
End Function

这些工作,所以我希望他们是对的。

现在可能与引用计数和何时调用撤销有关,但我现在可以调用 GetObject。

【讨论】:

  • 是的,我在评论中错过了这一点。正如您正确指出的那样,该对象需要先在 ROT 中注册,然后客户端才能附加到它。处理此步骤的一个好点是可执行文件的启动过程。至于引用计数,就看你怎么称呼RegisterActiveObject了。如果您使用 ACTIVEOBJECT_STRONG 标志,则需要从 ROT 中显式删除该对象。这可能是您正在寻找的行为。另一方面,ACTIVEOBJECT_WEAK 在最后一个客户端断开连接时释放对象。
  • @Aurora - 你有没有机会知道 ACTIVEOBJECT_STRONG 和 ACTIVEOBJECT_WEAK 的值?
  • 当然,ACTIVEOBJECT_STRONG = 0x0,ACTIVEOBJECT_WEAK = 0x1。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 2019-11-01
  • 2020-10-18
  • 2014-10-09
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多