2010-06-16 73 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 
相关问题