当前位置: 首页 > 面试题库 >

Java,Jacob和Microsoft Outlook事件:收到“找不到事件iid”错误

方季同
2023-03-14
问题内容

我正在编写一个使用Jacob库(桥接COM和Java)与Microsoft
Outlook进行交互的Java程序。该程序创建一个新的MailItem,向用户显示其Inspector窗口。我希望订阅检查器的Close事件,以了解用户何时完成其邮件项目的编辑。

要订阅的情况下,我跟着指示雅各的文档(约2 / 3下页):

当前的[event]模型在概念上类似于Visual Basic WithEvents 构造。基本上,我提供了一个名为的类,该类
com.jacob.com.DispatchEvents具有一个构造函数,该构造函数采用源对象(类型
com.jacob.com.Dispatch)和目标对象(任何类型)。向源对象查询其
IConnectionPointContainer接口,我尝试IConnectionPoint为其默认源接口(从中获取
IProvideClassInfo)获取一个
。同时,我还为默认源接口创建了DISPID到实际方法名称的映射。然后,我使用方法名称jmethodID 从目标Java对象获取句柄。
当前,所有事件方法都必须具有相同的签名:一个参数(它是Variants的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

根据Google的说法,其他一些人也收到了此错误。不幸的是,他们都没有得到答案。

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

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


问题答案:

一些实验后,我决定,我可以通过订阅达到预期效果MailItemClose情况下,而不是InspectorClose事件。我现在有一个MailItemEventHandler处理所有MailItem事件的类:

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



 类似资料:
  • 无论出于何种原因,我无法从laravel echo接收客户端的任何数据。我使用的是LaravelEcho服务器(socket.io)、redis广播和redis队列。据我所知,它们都是功能性的。我将带您了解如何为测试设置它。首先,我创建了一个UserCreated事件: 然后,为了测试此事件,我创建了一个CreateUser命令: 最后,这是我的laravel echo服务器。json: 接下来,

  • 收到请求事件 function onRequest(Request $request,Response $response); 当easySwoole收到任何的HTTP请求时,均会执行该事件。该事件可以对HTTP请求全局拦截。 $sec = new Security(); if($sec->check($request->getRequestParam())){ $response->wri

  • 这是一个紧凑的版本,请询问您是否需要澄清: 我已经成功注册了一个endpoint,这样当我在Dynamics CRM Online中更新属性(例如电话号码)时,一条消息就会发送到Azure Service Bus(主题和/或队列,这里没有区别)。我还有一个webjob,可以使用下面的签名监听这些更改: 这可以正常工作,当我更改例如电话号码时,我可以读取新的电话号码,并且所有其他属性都为空。但是,我

  • 我正在浏览一个列表以单击在阿尔基拉尔中找到的阿尔基拉尔按钮 我用XPATH以以下方式捕获它 但什么都没发生 查看我正在捕获的数据并返回按钮的名称 阿尔基拉尔 但是我不能点击按钮 我在问题打印中添加了一个答案(WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,“//a[text()='Alquilar']”)).t

  • 8.3.1 事件和事件对象 事件是针对应用程序所发生的事情,并且需要应用程序对它做出响应或进行处理。Tkinter中定义了很多种事件,足以支持常见的 GUI 应用程序开发。 Tkinter 事件可以用特定形式的字符串来描述,称为事件模式。事件模式的一般形式是: <modifier-type-detail> 其中类型符 type 指定事件类型,最常用的类型有分别表示鼠标事件和键盘事件的 Butto

  • 问题内容: 我正在使用与鼠标移动事件一起操作的YUI滑块。我想让它响应touchmove事件(iPhone和Android)。发生touchmove事件时如何产生鼠标移动事件?我希望仅在顶部添加一些脚本,即可将touchmove事件映射到鼠标移动事件,而无需使用滑块进行任何更改。 问题答案: 我确定这是您想要的: 我已经捕获了触摸事件,然后手动触发了自己的鼠标事件以进行匹配。尽管该代码并不是特别通