2

编辑:如果我重新启动 Excel,VBA 可以看到新方法。不过,我的问题仍然存在,尽管形式不同:如何强制 Excel 在不重新启动的情况下查看新方法?

我有一个简单的 COM 服务器,看起来像这样:

class COMServerThing:
    _public_methods_ = ["DoStupidThing"]
    _reg_progid_ = "COMServerThing.Utilities"
    _reg_clsid_ = "{A9DAECC7-2154-42E6-95B3-53A27EAB63E2}"

    def DoStupidThing(self):
        return 'foo'

我像这样注册它:

import win32com.server.register
win32com.server.register.UseCommandLine(COMServerThing)

这让我可以从 VBA 创建一个新的 COMServerThing 对象并从 Excel 调用我的 Python 代码。现在我想向这个服务器添加一个新方法。我试过做显而易见的事情:

class COMServerThing:
    # Add the new method to the list of public methods ...
    _public_methods_ = ["DoStupidThing", "AnotherStupidThing"]
    _reg_progid_ = "COMServerThing.Utilities"
    _reg_clsid_ = "{A9DAECC7-2154-42E6-95B3-53A27EAB63E2}"

    def DoStupidThing(self):
        return 'foo'

    # ... and implement it on the class.
    def AnotherStupidThing(self):
        return 42

这样做之后,我仍然无法从 VBA 访问新注册的方法。以下是我尝试过的其他一些无效的方法:

  • 我重新注册了服务器。
  • 我取消注册,然后重新注册服务器。
  • 我注销了服务器,更改了类 ID,然后重新注册了它。

唯一有效的是重命名服务器、更改其类 ID、重命名服务器所在的源文件以及注册新服务器——此时我们正在查看一个全新的 COM 服务器。

我不是 Windows/COM 开发人员,所以我很确定我错过了一些明显的东西。如何向已注册的 COM 服务器添加新方法?

4

1 回答 1

0

您是通过IDispatchEx公开您的方法,还是通过从 IUnknown 派生的自定义接口公开它们?

如果您要公开自定义接口,那么您很可能必须重新启动 Excel,因为您违反了COM 身份规则。即使使用IDispatch,文档也明确表示

成员和参数 DISPID 必须在对象的生命周期内保持不变。这允许客户端一次获取 DISPID,并缓存它们以供以后使用。

于 2013-10-24T04:43:24.450 回答