java com outlook events jacob

Eventos de Java, Jacob y Microsoft Outlook: recepción del error "No se puede encontrar el evento iid"



com events (3)

Después de un poco de experimentación, determiné que podía lograr el resultado deseado suscribiéndome al evento Close MailItem lugar del evento Close del Inspector . Ahora tengo una clase MailItemEventHandler que maneja todos los eventos de 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"); } }

Me suscribo a los eventos usando:

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

No sé mucho sobre COM, pero parece que hay algo mal con el registro de objetos Inspector ...

Estoy escribiendo un programa Java que interactúa con Microsoft Outlook utilizando la biblioteca Jacob (puentes COM y Java). Este programa crea un nuevo MailItem , mostrando su ventana de Inspector para el usuario. Deseo suscribirme al evento Close del inspector para saber cuándo el usuario ha terminado de editar su elemento de correo.

Para suscribirme al evento, seguí las instrucciones en la documentación de Jacob (aproximadamente 2/3 en la página):

El modelo actual de [evento] es conceptualmente similar al constructo WithEvents Visual Basic. Básicamente, com.jacob.com.DispatchEvents una clase llamada com.jacob.com.DispatchEvents que tiene un constructor que toma un objeto fuente (de tipo com.jacob.com.Dispatch ) y un objeto de destino (de cualquier tipo). El objeto de origen se consulta para su interfaz IConnectionPointContainer e intento obtener un IConnectionPoint para su interfaz de origen predeterminada (que IProvideClassInfo de IProvideClassInfo ). Al mismo tiempo, también creo una asignación de DISPID para la interfaz de origen predeterminada a los nombres de métodos reales. Luego uso los nombres del método para obtener los identificadores jmethodID del objeto Java objetivo. Todos los métodos de eventos actualmente deben tener la misma firma: un argumento que es una matriz de Java de variantes y un tipo de devolución de nulo.

Aquí está mi clase InspectorEventHandler , conforme a la documentación de 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) { } }

Y aquí es cómo me suscribo a los eventos usando esta clase 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);

Sin embargo, la última línea falla con la siguiente excepción:

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

Según Google , algunos otros también han recibido este error. Desafortunadamente, ninguno de ellos ha recibido una respuesta.

Estoy usando la versión 1.7 de la biblioteca de Jacob, que pretende evitar este problema:

La versión 1.7 también incluye código para leer la biblioteca de tipos directamente desde el programa. Esto hace posible trabajar con todos los eventos de aplicaciones de Microsoft Office, así como también con eventos IE5. Para ver un ejemplo, consulte el ejemplo samples / test / IETest.java.

Noté que el archivo IETest.java antes mencionado se suscribe a eventos como este:

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

Por lo tanto, intenté suscribirme a mis eventos de manera similar:

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

Todos estos intentos fallaron con el mismo error.


Quería adjuntarme al evento Close de una instancia de Word y obtuve un error similar si no colocaba el objeto Dispatch correcto en la lista de parámetros de DispatchEvents, pero esto funciona en mi caso, ahora.

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

y

import com.jacob.com.*; public class WordEventHandler { public void Close(Variant[] arguments) { System.out.println("closed word document"); } }


Jacob puede haber cambiado desde que intentabas hacer tu trabajo. Hoy, con Jacob 1.15-M3, logré recibir eventos de Excel, pero solo con el constructor de 4 argumentos:

DispatchEvents de = new DispatchEvents( sh, new Sink(), "Excel.Sheet", "C://Program Files (x86)//Microsoft Office//OFFICE11//EXCEL.EXE" );

Darle la ruta al ejecutable es bastante poco práctico, pero creo que es posible solucionarlo de alguna manera. Solo estaba haciendo pruebas, por lo que el ejecutable codificado estaba bien para mí.

Con menos argumentos recibí los mismos errores que tú:

Exception in thread "main" com.jacob.com.ComFailException: Can''t find event iid (...) GetEventIID: couldn''t get IProvideClassInfo