【问题标题】:Force a COM server to remain open强制 COM 服务器保持打开状态
【发布时间】:2015-09-21 02:54:44
【问题描述】:

我有一个由 VB6 exe 托管的 COM 自动化服务器

COM API 使用 Excel VBA

Dim o as MyCOMAPI.MyCOMType
Set o = new MyCOMAPI.MyCOMType
o.DoSomething

当我在 VBA 中创建对象时,exe 与 COM 自动化一起启动,VBA 可以使用 API。

但是 exe 被 Excel 快速“随机”关闭,我猜当 Excel 决定不再需要 COM API 时。

这种行为会导致随机错误。

简单的解决方案是在运行 VBA 代码之前启动 exe;在这种情况下,一切正常,因为 exe 在用户关闭之前不会停止运行。

您是否有一些关于 Excel VBA 管理对托管 API 的调用方式的信息/文档?

有没有办法避免这种行为并让 exe 保持打开状态,直到 VBA 代码决定停止它?

【问题讨论】:

    标签: excel vba com vb6 office-automation


    【解决方案1】:

    当最后一个对象被取消引用时,这将是 COM 自动化服务器的默认行为,这意味着指向服务器的变量被设置为空。

    现在,如果您的代码今天看起来像这样:

    Sub MyFunction()
    ...
    Dim o as MyCOMAPI.MyCOMType
    Set o = new MyCOMAPI.MyCOMType
    o.DoSomething
    End Sub
    

    然后,服务器寿命与 o 变量的寿命相关联。当函数完成时,该变量被设置为空,然后服务器将被关闭(除非有其他变量保持它处于活动状态)。

    为确保您的 COM 服务器能够长时间保持活动状态,只需将变量定义为公共变量,如下例所示。

    此示例将启动并显示 Excel 并保持打开状态,直到调用 ShutdownExcel 函数。

    Public o As Excel.Application
    
    Sub MakeSureExcelIsRunning()
        If o Is Nothing Then
            Set o = New Excel.Application
            o.Visible = True
        End If
    End Sub
    
    Sub ShutdownExcel()
        Set o = Nothing
    End Sub
    

    【讨论】:

    • 感谢您的回答。我通过在专用模块中公开一个公共对象来尝试类似的模式,但我猜即使在这种情况下,该对象也可以被 Excel 删除。所以也许我应该在我的所有模块中保留对它的引用,但我不确定它是否足够。无论如何,你会得到我的 +1,如果没有其他答案,我会接受。
    • 如果有一个未完成的变量引用您的 EXE 中的对象,Excel 将不会关闭该 EXE。请注意,仅执行全局 Dim v As New Libname.myClass起作用 - 大多数人认为它不会起作用 (stackoverflow.com/q/2478097/2230)。您必须从某处的 Function 或 Sub 手动 Set 它。
    【解决方案2】:

    来自 COM 文档。

     **Component Automation**  
    

    关闭对象

    ActiveX 对象必须按以下方式关闭:

    如果对象的应用程序可见,则对象应仅在响应明确的用户命令(例如,单击“文件”菜单上的“退出”)或来自 ActiveX 客户端的等效命令时关闭。

    如果对象的应用程序不可见,则对象应仅在最后一个外部引用消失时关闭。

    如果对象的应用程序是可见的并且由 ActiveX 客户端控制,那么当用户关闭它时(例如,单击“文件”菜单上的“退出”),它应该变得不可见。此行为允许控制器继续控制对象。仅当对对象的最后一个外部引用消失时,控制器才应关闭。

    © 微软公司。版权所有。

    当您编写 COM 服务器 exe 时,您做的第一件事就是在作为普通 exe 启动时引用您自己,否则该 exe 会在初始化结束后立即关闭。

    【讨论】:

      猜你喜欢
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多