Skip to content
qiannian edited this page Jun 13, 2026 · 1 revision

Java 调用示例

Java 可以通过 JACOB 创建 op.opsoft COM 对象。下面示例同时包含已注册 COM 调用和免注册调用方式。

准备依赖

Maven 示例:

<dependencies>
    <dependency>
        <groupId>com.hynnet</groupId>
        <artifactId>jacob</artifactId>
        <version>1.18</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>5.14.0</version>
    </dependency>
</dependencies>

JACOB 需要对应位数的 jacob-*.dll 可被 JVM 加载。Java 进程、JACOB DLL、tools.dllop_x86.dll/op_x64.dll 的位数必须一致。

已注册 COM 示例

适用于已经通过 regsvr32 或安装脚本注册过 op 插件的环境。

Code

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;

public class OpJavaDemo {
    public static void main(String[] args) {
        // 初始化当前线程的 COM 环境
        ComThread.InitSTA();
        try {
            // 创建 op COM 对象
            ActiveXComponent op = new ActiveXComponent("op.opsoft");

            // 调用 op.Ver()
            String version = Dispatch.call(op, "Ver").toString();
            System.out.println("op version: " + version);
        } finally {
            // 释放当前线程的 COM 环境
            ComThread.Release();
        }
    }
}

免注册示例

通过 tools.dllsetupW 加载 op_x86.dllop_x64.dll,不需要使用 regsvr32 注册插件。

示例假设程序运行目录下有如下结构:

app.jar
op/
  x86/
    tools.dll
    op_x86.dll
  x64/
    tools.dll
    op_x64.dll

Code

import java.io.File;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.WString;

public class OpJavaRegFreeDemo {
    public interface Tools extends Library {
        // setupW 是 cdecl 调用约定,JNA Library 默认使用 cdecl
        int setupW(WString path);
    }

    private static Tools toolsHandle;

    private static void setupOpRegFree(File pluginRoot) {
        // 根据当前 JVM 位数选择 x86 或 x64
        boolean isX64 = System.getProperty("os.arch").contains("64");
        String arch = isX64 ? "x64" : "x86";
        String opName = isX64 ? "op_x64.dll" : "op_x86.dll";

        File runtimeDir = new File(pluginRoot, arch);
        File toolsDll = new File(runtimeDir, "tools.dll");
        File opDll = new File(runtimeDir, opName);

        if (!toolsDll.isFile()) {
            throw new RuntimeException("找不到免注册工具: " + toolsDll.getAbsolutePath());
        }
        if (!opDll.isFile()) {
            throw new RuntimeException("找不到 op 插件: " + opDll.getAbsolutePath());
        }

        // 加载 tools.dll,并调用 setupW
        toolsHandle = Native.load(toolsDll.getAbsolutePath(), Tools.class);

        // setupW 必须在 ActiveXComponent 之前调用
        int ret = toolsHandle.setupW(new WString(opDll.getAbsolutePath()));
        if (ret != 1) {
            throw new RuntimeException("免注册加载失败: " + opDll.getAbsolutePath());
        }
    }

    public static void main(String[] args) {
        // 程序运行目录下的 op 目录,也可以改成自己的插件释放目录
        setupOpRegFree(new File("op"));

        // setupW 成功后,按普通 COM 方式创建对象
        ComThread.InitSTA();
        try {
            ActiveXComponent op = new ActiveXComponent("op.opsoft");
            String version = Dispatch.call(op, "Ver").toString();
            System.out.println("op version: " + version);
        } finally {
            ComThread.Release();
        }
    }
}

说明

  • setupW 只在当前进程内生效,不会写入系统注册表。
  • setupWcdecl 调用约定,JNA 的 Library 默认按 cdecl 调用。
  • tools.dll 安装了当前进程内的 COM Hook,加载成功后保持到进程退出即可。
  • 如果是 64 位 Java,请使用 x64/tools.dllx64/op_x64.dll
  • 如果是 32 位 Java,请使用 x86/tools.dllx86/op_x86.dll

Clone this wiki locally