【问题标题】:Java, Jacob and Microsoft Outlook events: Receiving "Can't find event iid" ErrorJava、Jacob 和 Microsoft Outlook 事件:接收“找不到事件 iid”错误
【发布时间】:2011-03-04 10:28:39
【问题描述】:

我正在编写一个使用Jacob library(桥接COM 和Java)与Microsoft Outlook 交互的Java 程序。该程序为用户创建了一个新的MailItemdisplayingInspector 窗口。我希望订阅检查员的Close event 以了解用户何时完成对其邮件项目的编辑。

要订阅该活动,我按照Jacob's documentation 中的说明进行操作(关于页面下方的23):

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

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

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

但是,最后一行失败并出现以下异常:

线程“主”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

According to Google,其他一些人也收到此错误。不幸的是,他们都没有收到答复。

我正在使用 Jacob 库的 1.7 版,它声称可以防止此问题:

1.7 版还包括阅读代码 类型库直接来自 天才。这使得工作成为可能 与所有 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");

所有这些尝试都因相同的错误而失败。

【问题讨论】:

    标签: java com outlook events jacob


    【解决方案1】:

    经过一些实验,我确定我可以通过订阅MailItem's Close event 而不是Inspector's Close event 来达到预期的效果。我现在有一个处理所有MailItem eventsMailItemEventHandler 类:

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

    【讨论】:

      【解决方案2】:

      Jacob 可能在您努力工作后发生了变化。今天,使用 Jacob 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
      

      【讨论】:

        【解决方案3】:

        我想附加到 Word 实例的 Close 事件,如果没有将正确的 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");
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-25
          相关资源
          最近更新 更多