代码之家  ›  专栏  ›  技术社区  ›  Adam Paynter

Java、雅各伯和微软Outlook事件:接收“找不到事件IID”错误

  •  2
  • Adam Paynter  · 技术社区  · 14 年前

    我正在编写一个Java程序,它与微软Outlook交互使用 Jacob library (桥接COM和Java)。此程序创建新的 MailItem , displaying 它的 Inspector 用户的窗口。我想订阅检查员的 Close event 了解用户何时完成对邮件项目的编辑。

    为了订阅该活动,我按照 Jacob's documentation (关于 周五 下页):

    当前的[事件]模型是概念上的 类似于Visual Basic WithEvents 构建。基本上,我提供了 类称为 com.jacob.com.DispatchEvents 哪个有 获取源的构造函数 对象(类型) com.jacob.com.Dispatch )和一个目标 对象(任何类型)。源头 查询对象的 IConnectionPointContainer 界面 我试图获得 IConnectionPoint 因为它的默认 源接口(我从中获得 IProvideClassInfo )同时, 我还创建了一个DispID的映射 对于默认的源接口 实际方法名称。然后我用 要获取的方法名称 jmethodID 来自目标Java对象的句柄。 当前所有事件方法都必须具有 相同的签名:一个参数 是一个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 ,其他一些人也收到了此错误。不幸的是,他们都没有收到答复。

    我正在使用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");
    

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

    3 回复  |  直到 12 年前
        1
  •  2
  •   Adam Paynter    14 年前

    经过一些实验,我决定通过订阅 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不太了解,但似乎有问题 检查员 对象注册…

        2
  •  1
  •   Jarekczek    12 年前

    雅各布可能已经改变了,因为你试图做你的工作。今天,有了Jacob1.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
  •  0
  •   Nick    12 年前

    我想附加到一个单词实例的close事件,如果没有将正确的分派对象放在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");
        }
    }
    
    推荐文章