diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index 080746b..5b9ef6e 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -59,6 +59,11 @@
Convert API to use var args and remove the many overloaded Dispatch
methods that each added one more parameter.(M4) |
+
+ | 2927058 |
+ a hasExited() method that allows polling until a COM server is
+ terminated and implemented this method in JACOB(M4) |
+
| |
|
diff --git a/jni/Dispatch.cpp b/jni/Dispatch.cpp
index 81868e6..04c6a89 100644
--- a/jni/Dispatch.cpp
+++ b/jni/Dispatch.cpp
@@ -555,6 +555,26 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
return newVariant;
}
+/*
+ * Wait method added so folks could wait until a com server terminated
+ */
+JNIEXPORT jint JNICALL Java_com_jacob_com_Dispatch_hasExited
+ (JNIEnv *env,jclass clazz, jobject disp, jint dispid, jint lcid) {
+ IDispatch *pIDispatch = extractDispatch(env, disp);
+ if (!pIDispatch) {
+ // should we return 0?
+ return NULL;
+ }
+ ITypeInfo *v;
+ HRESULT hr = pIDispatch->GetTypeInfo(dispid, lcid, &v);
+ if (hr == RPC_E_SERVERCALL_RETRYLATER || hr == RPC_E_CALL_REJECTED || hr
+ == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
}
diff --git a/jni/Dispatch.h b/jni/Dispatch.h
index 861f22e..6e4e731 100644
--- a/jni/Dispatch.h
+++ b/jni/Dispatch.h
@@ -81,6 +81,14 @@ JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
(JNIEnv *, jclass, jobject, jstring, jint, jint, jint, jobjectArray, jintArray);
+/*
+ * Class: Dispatch
+ * Method: wait
+ * Signature: (Ljava/lang/Object;I;)I
+ */
+JNIEXPORT jint JNICALL Java_com_jacob_com_Dispatch_hasExited
+ (JNIEnv *, jclass, jobject, jint, jint);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/com/jacob/com/Dispatch.java b/src/com/jacob/com/Dispatch.java
index a214afc..4902c46 100644
--- a/src/com/jacob/com/Dispatch.java
+++ b/src/com/jacob/com/Dispatch.java
@@ -845,4 +845,28 @@ public class Dispatch extends JacobObject {
throw new NotImplementedException("not implemented yet");
}
+ /**
+ * Cover for native method
+ *
+ * @param disp
+ * @param dispid
+ * @param lcid
+ * @return 0 if the dispatch is still active and 1 if it has exited
+ */
+ public static native int hasExited(Dispatch disp, int dispid, int lcid);
+
+ /**
+ * The method is used to poll until it returns 1, indicating that the COM
+ * server in gone.
+ *
+ * Sourceforge feature request 2927058
+ *
+ * @param dispatchTarget
+ * @return 0 if the dispatch is still active and 1 if it has exited
+ */
+ public static int hasExited(Dispatch dispatchTarget) {
+ throwIfUnattachedDispatch(dispatchTarget);
+ return hasExited(dispatchTarget, 0, LOCALE_SYSTEM_DEFAULT);
+ }
+
}
diff --git a/unittest/com/jacob/com/DispatchTest.java b/unittest/com/jacob/com/DispatchTest.java
index eef7dc1..5cbde73 100644
--- a/unittest/com/jacob/com/DispatchTest.java
+++ b/unittest/com/jacob/com/DispatchTest.java
@@ -1,5 +1,6 @@
package com.jacob.com;
+import com.jacob.activeX.ActiveXComponent;
import com.jacob.test.BaseTestCase;
/**
@@ -12,9 +13,21 @@ import com.jacob.test.BaseTestCase;
public class DispatchTest extends BaseTestCase {
/**
- * Dummy test until someone gets their act together
+ * Verify this detects word's exit
*/
- public void testDispatch() {
- // what should we test
+ public void testDispatchHasExited() {
+ String pid = "Word.Application";
+ ActiveXComponent axc = new ActiveXComponent(pid);
+ assertEquals(0, Dispatch.hasExited(axc));
+ axc.invoke("Quit", new Variant[] {});
+ // should take some amount of time for Word to Quit so should = !exited
+ assertEquals(0, Dispatch.hasExited(axc));
+ try {
+ // sleep some reasonable amount of time waiting for it to quit
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ fail("should not have been interrupted");
+ }
+ assertEquals(1, Dispatch.hasExited(axc));
}
}