2013-10-23 84 views
2

編輯:原來如果我重新啓動Excel,VBA可以看到新的方法。不過,我的問題依然存在,儘管形式不同:如何強制Excel在不重新啓動的情況下查看新方法?如何將新方法添加到我已經註冊的COM服務器中?

我有一個看起來像這樣一個簡單的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對象,並調用我的Python來自Excel的代碼。現在我想添加一個新的方法到這個服務器。我已經嘗試做明顯的事情:

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服務器中?

+0

我通常會首先殺死COM對象。然後重新編譯服務器(新版本),回到Excel並重新附加引用到我的COM,它的工作原理。我無法重現您確切的問題,但請確保在重新連接之前重新構建您的COM(包括.dll和.tlb)。 – 2013-10-23 07:16:48

+0

您是否嘗試過獨立和inproc com服務器?我相信要記住,其中一人在你的問題上工作。您需要在服務器定義中設置_reg_clsctx = pythoncom.CLSCTX_INPROC_SERVER或CLSCTX_LOCAL_SERVER之一。 –

回答

0

您是通過IDispatchEx公開您的方法,還是通過派生自IUnknown的自定義接口公開它們?

如果您公開自定義界面,那麼您很可能必須重新啓動Excel,因爲您打破了COM identity rules。即使IDispatch,文件明確表示,

成員和參數的DISPID必須爲對象的生命週期 保持不變。這允許客戶端獲得一次DISPID,並且將其緩存以供以後使用。

相關問題