您好我目前的任务是转换通过第三方应用程序XFS.ocx(无源)与Passbook打印机通信的传统Visual Basic 6应用程序.
根据我的研究,我可以让JACOB完成这项任务,但我遇到了一个错误.谁能帮我?基于日志,我的程序可以实例化activeXcomponent并查看我想要使用的方法的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");
Run Code Online (Sandbox Code Playgroud)
这是我遇到的日志和错误
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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我的猜测是 Description 是一个只读属性,而不是一个函数
所以你不能对它使用调用,并且此代码会出现错误,从而产生灾难性的失败(COM 错误始终是模糊的):
activeXComponent.call(activeXComponent, "Description", "value");
正如消息日志所解释的:
线程“主”com.jacob.com.ComFailException 中出现异常:遇到 COM 异常:调用时:说明
并且您也无法设置属性,因为它是只读的:
activeXComponent.setProperty("Description", "Description");
实际上,如果您正确地阅读了 VB6 代码,则只是读取了 Description 属性
sDescription = XFS1.Description
Run Code Online (Sandbox Code Playgroud)
试试这个:
Variant v = activeXComponent.call(activeXComponent, "Description");
String description = v.toString();