2010-06-16 71 views
2

我正在編寫一個Java程序,它使用Jacob library(橋接COM和Java)與Microsoft Outlook進行交互。該程序爲用戶創建一個新的MailItem,displayingInspector窗口。我希望訂閱檢查員的Close event以瞭解用戶何時完成編輯郵件項目。Java,Jacob和Microsoft Outlook事件:接收「無法找到事件iid」錯誤

要訂閱的情況下,我也跟着在Jacob's documentation指令(約 ⁄ 向下頁):

當前[事件]模型是概念性 類似的Visual Basic WithEvents 構造。基本上,我提供了一種 類稱爲 com.jacob.com.DispatchEvents具有 一個構造函數源 對象( com.jacob.com.Dispatch類型)和目標對象 (任何類型的)。源 對象查詢其 IConnectionPointContainer接口 和我嘗試獲得其默認 源接口的 IConnectionPoint(我從 IProvideClassInfo獲得)。同時, 我還創建了默認源接口的DISPID的 到 實際方法名稱的映射。然後我使用方法名稱 從目標Java對象獲取jmethodID 句柄。 所有事件方法當前必須有 相同的簽名:一個參數,其中 是Variant的Java數組,以及 void返回類型。

這裏是我InspectorEventHandler類,符合雅各布的文檔:

public class InspectorEventHandler { 

    public void Activate(Variant[] arguments) { 

    } 

    public void BeforeMaximize(Variant[] arguments) { 

    } 

    public void BeforeMinimize(Variant[] arguments) { 

    } 

    public void BeforeMove(Variant[] arguments) { 

    } 

    public void BeforeSize(Variant[] arguments) { 

    } 

    public void Close(Variant[] arguments) { 
     System.out.println("Closing"); 
    } 

    public void Deactivate(Variant[] arguments) { 

    } 

    public void PageChange(Variant[] arguments) { 

    } 

} 

這裏是如何訂閱使用此InspectorEventHandler類的事件:

Object outlook = new ActiveXComponent("Outlook.Application"); 
Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch(); 
Object inspector = Dispatch.get(mailItem, "GetInspector").getDispatch(); 

InspectorEventHandler eventHandler = new InspectorEventHandler(); 

// This supposedly registers eventHandler with the inspector 
new DispatchEvents((Dispatch) inspector, eventHandler); 

不過,最後線路發生故障,但有以下例外:

 
Exception in thread "main" com.jacob.com.ComFailException: Can't find event iid 
    at com.jacob.com.DispatchEvents.init(Native Method) 
    at com.jacob.com.DispatchEvents.(DispatchEvents.java) 
    at cake.CakeApplication.run(CakeApplication.java:30) 
    at cake.CakeApplication.main(CakeApplication.java:15) 
couldn't get IProvideClassInfo 

According to Google,其他一些人也收到了這個錯誤。不幸的是,他們中沒有人收到答覆。

我現在用的是雅各布庫,號稱防止這個問題的1.7版:

1.7版還包括代碼直接從 的progid讀 類型庫。這使得可以將所有Microsoft Office 應用程序事件以及IE5 事件與 一起工作。有關示例,請參閱 samples/test/IETest.java示例。

我注意到,上述IETest.java文件贊同這樣的事件:

new DispatchEvents((Dispatch) ieo, ieE,"InternetExplorer.Application.1"); 

因此,我想訂閱我的事件用類似的方式:

new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application"); 
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.1"); 
new DispatchEvents((Dispatch) inspector, eventHandler, "Outlook.Application.12"); 

所有這些嘗試都失敗了與同樣的錯誤。

回答

2

經過一番實驗,我確定我可以通過訂閱MailItem's Close event而不是Inspector's Close event來達到預期的效果。我現在有一個MailItemEventHandler類來處理所有MailItem events

public class MailItemEventHandler { 

    public void AttachmentAdd(Variant[] arguments) { 
     System.out.println("AttachmentAdd"); 
    } 

    public void AttachmentRead(Variant[] arguments) { 
     System.out.println("AttachmentRead"); 
    } 

    public void AttachmentRemove(Variant[] arguments) { 
     System.out.println("AttachmentRemove"); 
    } 

    public void BeforeAttachmentAdd(Variant[] arguments) { 
     System.out.println("BeforeAttachmentAdd"); 
    } 

    public void BeforeAttachmentPreview(Variant[] arguments) { 
     System.out.println("BeforeAttachmentPreview"); 
    } 

    public void BeforeAttachmentRead(Variant[] arguments) { 
     System.out.println("BeforeAttachmentRead"); 
    } 

    public void BeforeAttachmentSave(Variant[] arguments) { 
     System.out.println("BeforeAttachmentSave"); 
    } 

    public void BeforeAttachmentWriteToTempFile(Variant[] arguments) { 
     System.out.println("BeforeAttachmentWriteToTempFile"); 
    } 

    public void BeforeAutoSave(Variant[] arguments) { 
     System.out.println("BeforeAutoSave"); 
    } 

    public void BeforeCheckNames(Variant[] arguments) { 
     System.out.println("BeforeCheckNames"); 
    } 

    public void BeforeDelete(Variant[] arguments) { 
     System.out.println("BeforeDelete"); 
    } 

    public void Close(Variant[] arguments) { 
     System.out.println("Close"); 
    } 

    public void CustomAction(Variant[] arguments) { 
     System.out.println("CustomAction"); 
    } 

    public void CustomPropertyChange(Variant[] arguments) { 
     System.out.println("CustomPropertyChange"); 
    } 

    public void Forward(Variant[] arguments) { 
     System.out.println("Forward"); 
    } 

    public void Open(Variant[] arguments) { 
     System.out.println("Open"); 
    } 

    public void PropertyChange(Variant[] arguments) { 
     System.out.println("PropertyChange"); 
    } 

    public void Read(Variant[] arguments) { 
     System.out.println("Read"); 
    } 

    public void Reply(Variant[] arguments) { 
     System.out.println("Reply"); 
    } 

    public void ReplyAll(Variant[] arguments) { 
     System.out.println("ReplyAll"); 
    } 

    public void Send(Variant[] arguments) { 
     System.out.println("Send"); 
    } 

    public void Unload(Variant[] arguments) { 
     System.out.println("Unload"); 
    } 

    public void Write(Variant[] arguments) { 
     System.out.println("Write"); 
    } 

} 

我訂閱事件使用:

Object outlook = new ActiveXComponent("Outlook.Application"); 
Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch(); 

MailItemEventHandler eventHandler = new MailItemEventHandler(); 
new DispatchEvents((Dispatch) mailItem, eventHandler); 

我不知道很多有關COM,但它似乎有什麼毛病Inspector對象註冊...

0

我想附加到一個Word實例的關閉事件,並得到類似的錯誤,如果沒有把正確的Dispatch對象放在DispatchEvents的參數列表中,但這在我的情況下,現在。

ActiveXComponent oWord = new ActiveXComponent("Word.Application"); 
oWord.setProperty("Visible", new Variant(true)); 
Dispatch oDocuments = oWord.getProperty("Documents").toDispatch(); 
Dispatch oDocument = Dispatch.call(oDocuments, "Open", strInputDoc).toDispatch(); 
WordEventHandler w = new WordEventHandler(); 
new DispatchEvents(oDocument, w); 

import com.jacob.com.*; 

public class WordEventHandler { 
    public void Close(Variant[] arguments) { 
     System.out.println("closed word document"); 
    } 
} 
1

雅各布可能已經改變,因爲你試圖做你的工作。今天,雅各1.15-M3,我設法從Excel接收事件,但只能使用4參數的構造函數:

DispatchEvents de = new DispatchEvents(
    sh, 
    new Sink(), 
    "Excel.Sheet", 
    "C:\\Program Files (x86)\\Microsoft Office\\OFFICE11\\EXCEL.EXE" 
); 

給可執行文件的路徑是相當不可移植的,但我想這是可能以某種方式變通辦法。我只是在做測試,所以硬編碼的可執行文件對我來說可以。

用較少的論點我收到了同樣的錯誤,你:

Exception in thread "main" com.jacob.com.ComFailException: Can't find event iid 
(...) 
GetEventIID: couldn't get IProvideClassInfo 
相關問題