JACOB调用.OCX方法时发生灾难性故障

8

您好,我目前的任务是将一个遗留的Visual Basic 6应用程序转换为通过第三方应用程序XFS.ocx与Passbook打印机通信。

根据我的研究,我可以使用JACOB来完成这个任务,但我遇到了一个错误。有人能帮帮我吗?根据日志,我的程序可以实例化ActiveX组件并查看我想要使用的方法的ID,但是当我尝试使用它们时,我会遇到一个错误。

在我使用作为指南的示例VB6代码中,方法 VersionRequired 需要两个整数作为参数,而 ApplicationID 仅需要一个字符串。

希望我只是语法或JACOB方法上犯了一个错误,因为我只想作为最后的手段使用Java JNI。请注意,此应用程序将始终安装在Windows(7/10)工作站上,因此其他操作系统的兼容性不是问题。

这是我的代码

ActiveXComponent activeXComponent = new ActiveXComponent("XFS.XFSCtrl.1");


System.out.println( activeXComponent.getIDOfName(activeXComponent, "ApplicationID"));
System.out.println( activeXComponent.getIDOfName(activeXComponent, "VersionRequired")); 
System.out.println( activeXComponent.getIDOfName(activeXComponent, "Description"));
System.out.println( activeXComponent.getIDOfName(activeXComponent, "Open"));

//Variant variant = activeXComponent.call(activeXComponent, "VersionRequired",1,1);
//Variant variant = activeXComponent.call(activeXComponent, "Description"); // added 072318 for David answer
//Variant variant = activeXComponent.getProperty("Description");
//activeXComponent.setProperty("Description", "Description");
//Variant variant = activeXComponent.get(activeXComponent,"Description");
activeXComponent.call(activeXComponent, "Description", "value");

以下是我遇到的日志和错误信息

WARNING: JNI local refs: zu, exceeds capacity: zu
    at java.lang.System.initProperties(Native Method)
    at java.lang.System.initializeSystemClass(System.java:1166)
main: Loading library jacob-1.19-x86 using System.loadLibrary 
main: Loading library jacob-1.19-x86 using System.loadLibrary 
main: Loading library jacob-1.19-x86 using System.loadLibrary 
main: ComThread: before Init: 0
main: ComThread: after Init: 0
main: ROT: Automatic GC flag == false
main: ComThread: after ROT.addThread: 0
main: ROT: adding com.jacob.activeX.ActiveXComponent@11d50c0->com.jacob.activeX.ActiveXComponent table size prior to addition:0
13
31
1
21
main: ROT: adding ->com.jacob.com.Variant table size prior to addition:1
main: ROT: adding ->com.jacob.com.Variant table size prior to addition:2
main: ROT: adding ->com.jacob.com.Variant table size prior to addition:3
main: ROT: adding ->com.jacob.com.Variant table size prior to addition:4
main: ROT: adding ->com.jacob.com.Variant table size prior to addition:5
Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: Description
Description: 8000ffff / Catastrophic failure

    at com.jacob.com.Dispatch.invokev(Native Method)
    at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
    at com.jacob.com.Dispatch.callN(Dispatch.java:453)
    // at com.jacob.com.Dispatch.get(Dispatch.java:788) // added 072318 when using activeXComponent.get(activeXComponent,"Description")
    at com.jacob.com.Dispatch.call(Dispatch.java:541)
    // at com.jacob.com.Dispatch.call(Dispatch.java:529) // added 072318 for David answer
    at ph.com.bdo.icos.passbook.Launcher.main(Launcher.java:32)

我参考的VB代码

  With XFS1
        'Set up the versions required of XFS and SP
        .VersionRequired(WFS_VERSREQ_OLE, WFS_VERSREQ_LOW) = 1#   ' 2.00
        .VersionRequired(WFS_VERSREQ_OLE, WFS_VERSREQ_HIGH) = 2#  ' 2.00
        .VersionRequired(WFS_VERSREQ_API, WFS_VERSREQ_LOW) = 1.01
        .VersionRequired(WFS_VERSREQ_API, WFS_VERSREQ_HIGH) = 2#
        .VersionRequired(WFS_VERSREQ_SRV, WFS_VERSREQ_LOW) = 1.01
        .VersionRequired(WFS_VERSREQ_SRV, WFS_VERSREQ_HIGH) = 2.1
        'Get back one of the values for testing
        fResult = .VersionRequired(WFS_VERSREQ_API, WFS_VERSREQ_LOW)

        'Set and Get the Application property for testing
        .ApplicationID = "Passbook Printer"
        sAppID = .ApplicationID
        sDescription = .Description

1
你使用的是哪个JDK(Oracle/OpenJDK/...)? - Javier Toja
2
在vb6代码中,您没有初始化.Description,这是某种全局变量还是其他什么东西吗?堆栈跟踪显示了以下内容:Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered: At Invoke of: Description - Javier Toja
你好karelss 1)Oracle - jdk1.8.0_172 2)在VB代码中,我使用的是本地变量,并且在使用之前没有初始化,但它没有抛出错误。 在我的代码中,我只是想表明我认为(可能是错误的),我能够初始化目标.OCX,因为我能够获得方法ID。然而,当我尝试使用任何方法时,我遇到了相同的“8000ffff /灾难性故障”错误。 - Jefrey Valencia
1个回答

3
我的猜测是Description是一个只读属性,而不是一个函数,因此您不能在它上面使用call方法,否则会出现严重的失败(COM错误一直以来都很难理解):
activeXComponent.call(activeXComponent, "Description", "value");
根据消息日志的说明:
“Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered: At Invoke of: Description”
另外,您也不能设置属性,因为它是只读的:
activeXComponent.setProperty("Description", "Description");
实际上,如果您正确阅读VB6代码,Description属性只能读取。
sDescription = XFS1.Description

尝试使用以下代码替换原始代码:
``` Variant v = activeXComponent.call(activeXComponent, "Description"); String description = v.toString(); ```
该代码与原始代码相同,但是更易读懂。

嗨,David!感谢您的回复。很抱歉我之前已经尝试过那种方法,但是忘记在问题中记录下来了(现已更新)。它在Dispatch.Java类中产生了相同的异常,只是在不同的行上(541->529)。 - Jefrey Valencia
1
这个怎么样:Dispatch.get(activeXComponent, "Description")? - David Doumèche
1
同时jvm的体系结构应该与OCX保持一致,即32位。 - David Doumèche
嗨,David!感谢回复。我已经按照你的建议更新了我的问题,但在Dispatch.Java的另一个部分仍然出现相同的异常。我使用System.getProperty("sun.arch.data.model")再次检查了版本,输出为32。 - Jefrey Valencia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接