Jawin 和 JUnit

Jawin and JUnit

我正在使用 Jawin 通过 COM 访问 Windows 应用程序。我的代码工作正常。我在 Java 中编写了一个简单的测试,它按预期执行。但是,当我使用 @Test 注释此方法并通过 JUnit 环境执行它时,代码抛出 COMException:

org.jawin.COMException: 80020009: Failed to get item[src=OMTE.Projects.6,guid={C9FF8402-BB2E-11D0-8475-0080C82BFA0C}]
at org.jawin.marshal.GenericStub.dispatchInvoke0(Native Method)
at org.jawin.marshal.GenericStub.dispatchInvoke(GenericStub.java:201)
at org.jawin.DispatchPtr.invokeN(DispatchPtr.java:587)
at org.jawin.DispatchPtr.invokeN(DispatchPtr.java:555)
at org.eclipse.epsilon.emc.ptcim.AttributeRelatedTests.getProject(AttributeRelatedTests.java:42)
at org.eclipse.epsilon.emc.ptcim.AttributeRelatedTests.testModelId(AttributeRelatedTests.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Java代码:

public static void main (String args[]) {
        testModelId(); // try/catch was removed for better presentation
}

public static void testModelId() throws COMException {
    Ole32.CoInitialize();
    DispatchPtr theProject = getProject("Traffic Lights");
    DispatchPtr model = load(theProject);
    DispatchPtr rootItem = (DispatchPtr) model.invoke("Item", "Package", "Software");
    String strObjId = (String) rootItem.get("Property", "Id");
    assertEquals("80a27e73-0121-436a-abf7-1e01ebb33c7e", strObjId);
}


protected static DispatchPtr getProject(String name) throws COMException {
    Ole32.CoInitialize();
    DispatchPtr app = new DispatchPtr("OMTE.Projects");
    String Role = "Project";
    DispatchPtr dispPtr = (DispatchPtr) app.invokeN("Item", new Object[] {
            Role, name});
    DispatchPtr modelRef = new DispatchPtr();
    modelRef.stealUnknown(dispPtr);
    return modelRef;
}

// load method is not included as the exception is thrown at getProject method

JUnit代码:

@Test
public void testModelId() throws COMException {
    Ole32.CoInitialize();
    DispatchPtr theProject = getProject("Traffic Lights");
    DispatchPtr model = load(theProject);
    DispatchPtr rootItem = (DispatchPtr) model.invoke("Item", "Package", "Software");
    String strObjId = (String) rootItem.get("Property", "Id");
    assertEquals("80a27e73-0121-436a-abf7-1e01ebb33c7e", strObjId);
}


protected static DispatchPtr getProject(String name) throws COMException {
    Ole32.CoInitialize();
    DispatchPtr app = new DispatchPtr("OMTE.Projects");
    String Role = "Project";
    DispatchPtr dispPtr = (DispatchPtr) app.invokeN("Item", new Object[] {
            Role, name});
    DispatchPtr modelRef = new DispatchPtr();
    modelRef.stealUnknown(dispPtr);
    return modelRef;
}

第一个是 运行 作为 Java 应用程序,第二个是 JUnit4 测试配置。

这就是我所做的,这对我有用:

我尝试 运行使用 JUnit 运行 配置从另一台机器进行相同的测试,并且它们 运行 成功。两台机器之间有一个主要区别,即操作系统(Windows 10 vs Windows 7)。两台机器都安装了 Eclipse Mars 2。将我的 OS 降级(从不起作用的 Windows 10 降级到起作用的 Windows 7)是一种矫枉过正,所以我决定尝试更新的 Eclipse 版本,希望它们之间存在一些不兼容性Win 10 + Eclipse Mars 2 + JUnit 已在较新版本中修复。事实上,同样的测试 运行 在 Eclipse Neon in Windows 10.

中完美

从解决问题所采取的行动来看,我的理解是 Eclipse Mars 2 + Windows 10(64 位)+ JUnit 在特定情况下不兼容(这些情况可能涉及也可能不涉及使用Jawin 2.0 alpha 库)。