Java、Jacob 和 Microsoft Outlook 事件:接收“找不到事件 iid"错误 [英] Java, Jacob and Microsoft Outlook events: Receiving "Can't find event iid" Error

查看:22
本文介绍了Java、Jacob 和 Microsoft Outlook 事件:接收“找不到事件 iid"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 Java 程序,该程序使用 Jacob 库(桥接 COM 和 Java).该程序创建了一个新的 MailItem显示Inspector 窗口给用户.我想订阅检查员的关闭事件 知道用户何时完成编辑他们的邮件项目.

为了订阅该活动,我按照Jacob 的文档(关于23 向下):

<块引用>

当前的[事件]模型在概念上是类似于 Visual Basic WithEvents构造.基本上,我提供了一个班级被称为com.jacob.com.DispatchEvents 其中有一个接受源的构造函数对象(类型com.jacob.com.Dispatch) 和一个目标对象(任何类型).来源查询对象的IConnectionPointContainer 接口我试图获得一个IConnectionPoint 为其默认值源接口(我从IPprovideClassInfo).同时,我还创建了一个 DISPID 的映射对于默认源接口实际的方法名称.然后我用获取jmethodID的方法名来自目标 Java 对象的句柄.目前所有的事件方法都必须有相同的签名:一个参数是一个 Java 变体数组,和一个void 返回类型.

这是我的 InspectorEventHandler 类,符合 Jacob 的文档:

公共类InspectorEventHandler {公共无效激活(变体 [] 参数){}public void BeforeMaximize(Variant[] arguments) {}public void BeforeMinimize(Variant[] arguments) {}public void BeforeMove(Variant[] arguments) {}public void BeforeSize(Variant[] arguments) {}公共无效关闭(变体 [] 参数){System.out.println("结束");}公共无效停用(变体 [] 参数){}public void PageChange(Variant[] arguments) {}}

这里是我如何使用这个 InspectorEventHandler 类订阅事件:

Object Outlook = new ActiveXComponent("Outlook.Application");Object mailItem = Dispatch.call(outlook, "CreateItem", 0).getDispatch();对象检查器 = Dispatch.get(mailItem, "GetInspector").getDispatch();InspectorEventHandler eventHandler = new InspectorEventHandler();//这应该是向检查器注册 eventHandlernew DispatchEvents((Dispatch) 检查器,eventHandler);

然而,最后一行失败并出现以下异常:

<前>线程main"com.jacob.com.ComFailException 中的异常:找不到事件 iid在 com.jacob.com.DispatchEvents.init(本机方法)在 com.jacob.com.DispatchEvents.(DispatchEvents.java)在 cake.CakeApplication.run(CakeApplication.java:30)在 cake.CakeApplication.main(CakeApplication.java:15)无法获得 IProvideClassInfo

根据谷歌,其他一些人也收到此错误.不幸的是,他们都没有得到答复.

我使用的是 Jacob 库的 1.7 版,它声称可以防止这个问题:

<块引用>

1.7 版还包含代码以供阅读类型库直接来自程序.这使得工作成为可能与所有 Microsoft Office应用程序事件,以及 IE5事件.有关示例,请参见示例/测试/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");

所有这些尝试都以相同的错误失败.

解决方案

经过一些实验,我确定通过订阅 MailItemClose 事件 而不是 Inspector关闭事件.我现在有一个 MailItemEventHandler 类来处理所有 MailItem 事件:

public class MailItemEventHandler {public void AttachmentAdd(Variant[] arguments) {System.out.println("附件添加");}public void AttachmentRead(Variant[] arguments) {System.out.println("附件读取");}public void AttachmentRemove(Variant[] arguments) {System.out.println("附件删除");}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");}公共无效关闭(变体 [] 参数){System.out.println("关闭");}public void CustomAction(Variant[] arguments) {System.out.println("CustomAction");}public void CustomPropertyChange(Variant[] arguments) {System.out.println("CustomPropertyChange");}公共无效转发(变体[]参数){System.out.println("转发");}public void Open(Variant[] 参数) {System.out.println("打开");}public void PropertyChange(Variant[] 参数) {System.out.println("属性更改");}公共无效读取(变体 [] 参数){System.out.println("读取");}公共无效回复(变体 [] 参数){System.out.println("回复");}public void ReplyAll(Variant[] arguments) {System.out.println("ReplyAll");}公共无效发送(变体 [] 参数){System.out.println("发送");}公共无效卸载(变体[]参数){System.out.println("卸载");}公共无效写入(变体 [] 参数){System.out.println("写");}}

我订阅事件使用:

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 对象注册有问题...

I am writing a Java program that interacts with Microsoft Outlook using the Jacob library (bridges COM and Java). This program creates a new MailItem, displaying its Inspector window to the user. I wish to subscribe to the inspector's Close event to know when the user is finished editing their mail item.

To subscribe to the event, I followed the instructions in Jacob's documentation (about 23 down the page):

The current [event] model is conceptually similar to the Visual Basic WithEvents construct. Basically, I provide a class called com.jacob.com.DispatchEvents which has a constructor that takes a source object (of type com.jacob.com.Dispatch) and a target object (of any type). The source object is queried for its IConnectionPointContainer interface and I attempt to obtain an IConnectionPoint for its default source interface (which I obtain from IProvideClassInfo). At the same time, I also create a mapping of DISPID's for the default source interface to the actual method names. I then use the method names to get jmethodID handles from the target Java object. All event methods currently must have the same signature: one argument which is a Java array of Variants, and a void return type.

Here is my InspectorEventHandler class, conforming to Jacob's documentation:

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) {

    }

}

And here is how I subscribe to the events using this InspectorEventHandler class:

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);

However, the last line fails with the following exception:

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, a few others have also received this error. Unfortunately, none of them have received an answer.

I am using version 1.7 of the Jacob library, which claims to prevent this problem:

Version 1.7 also includes code to read the type library directly from the progid. This makes it possible to work with all the Microsoft Office application events, as well as IE5 events. For an example see the samples/test/IETest.java example.

I noticed that the aforementioned IETest.java file subscribes to events like this:

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

Therefore, I tried subscribing to my events in a similar manner:

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

All these attempts failed with the same error.

解决方案

After some experimentation, I determined that I could achieve the desired result by subscribing to the MailItem's Close event rather than the Inspector's Close event. I now have a MailItemEventHandler class that handles all 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");
    }

}

I subscribe to the events using:

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

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

I don't know much about COM, but it appears that there is something wrong with the Inspector object registration...

这篇关于Java、Jacob 和 Microsoft Outlook 事件:接收“找不到事件 iid"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆