目录
2.2将jacob-1.18-x64.dll放到C:\Windows\System32文件夹下
4.1com.jacob.com.ComFailException: Can't map name to dispid
4.2com.jacob.com.ComFailException: Can't co-create object
4.3com.jacob.com.ComFailException: Can't get object clsid from progid
1.编写DLL
1.1新建项目(Visual Studio)
1.2编写测试用例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyTest
{
public class TestClass
{
/**
* public TestClass()测试用例 传入两个整数,返回两个整数之和
* 此方法不能用static修饰,不然在java端调用时会报错
* com.jacob.com.ComFailException: Can't map name to dispid:sum
*/
public int sum(int a, int b) {
int tem = a + b;
return tem;
}
}
}
1.3生成解决方案,导出DLL
以下设置必须要有,不然会在注册dll的时候不提示“成功注册了类型”
生成-生成解决方案
1.4第一次生成解决方案时报错的处理办法
1.4.1出现“无法注册程序集dll- 拒绝访问。请确保您正在以管理员身份运行应用程序。对注册表项的访问被拒绝
WIN+R,运行对话框中输入gpedit.msc,开启组策略
在“计算机配置”-“Windows 设置”-“安全设置”-“本地策略”-“安全选项”-找到右侧的
“用户账户控制:以管理员批准模式运行所有管理员”这个项,把它设成禁用
2.本地注册DLL
2.1下载jacob-1.18(下载地址如下)
https://github.com/freemansoft/jacob-project/releases/tag/Root_B-1_18
2.2将jacob-1.18-x64.dll放到C:\Windows\System32文件夹下
2.3注册自己写的组件
2.3.1将步骤1生成的dll放到 D:\java\dll(目录自己随意,我的是这个目录)
2.3.2 用管理员身份打开命令提示符
2.3.3在cmd中跳转到C:\Windows\Microsoft.NET\Framework64下版本最高的framework版本下
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
2.3.4注册DLL
Regasm D:\java\dll\MyTest.dll /tlb:D:\java\dll\MyTest.tlb
如果提示下边这个(即只提示成功导出,不提示成功注册),说明导出的dll没有根据步骤1.3导出设置进行设置
2.3.4将导出的DLL放到jdk的bin目录下
每个人的jdk安装目录不一样,放到自己的安装目录下即可
C:\Program Files\Java\jdk1.8.0_144\bin
3.java调用
3.1pom.xml引入jar包
<dependency>
<groupId>com.hynnet</groupId>
<artifactId>jacob</artifactId>
<version>1.18</version>
</dependency>
3.2程序调用
package cn.main.xx;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* TODO
* @author Mengwx
* @version 1.0
* @date 2022/10/21 14:15
*/
public class Test {
public static void main(String[] args) {
Test test=new Test();
test.testJacob();
test.add(1,2);
}
/**
* 测试jacob组件
* 只作为测试jacob好用不好用
* 如果遇到报错则 检查jacob-1.18-x64.dll有没有放到C:\Windows\System32文件夹下
*/
public void testJacob() {
ActiveXComponent xl = new ActiveXComponent("Excel.Application");
Dispatch xlo = xl.getObject();
try {
System.out.println("jacob's version="+xl.getProperty("Version"));
System.out.println("jacob's version="+Dispatch.get(xlo, "Version"));
} catch (Exception e) {
e.printStackTrace();
} finally {
xl.invoke("Quit", new Variant[] {});
}
}
/**
* 测试dll
*/
public void add(int a,int b) {
try {
// 启动jacob线程
ComThread.InitSTA();
// MyTest 是要调用方法的命名空间namespace
// TestClass 要调用方法的类名class
ActiveXComponent com = new ActiveXComponent("MyTest.TestClass");
// Dispatch对象看成是对COM组件的对象
Dispatch dispatch = com.getObject();
//sum是MyTest.dll中的一个方法 后边是传入的参数
Variant ret = Dispatch.call(dispatch, "sum",a,b);
//打印结果
System.out.println("Dll返回的结果为"+ret.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 结束jacob所有线程
ComThread.Release();
}
}
}
4.记录调用dll时的报错及解决办法
4.1com.jacob.com.ComFailException: Can't map name to dispid
dll中的方法不能用static修饰
4.2com.jacob.com.ComFailException: Can't co-create object
dll导出时候没有根据步骤1.3导出(我觉得大概率是dll属性中没勾选为COM互操作注册)
4.3com.jacob.com.ComFailException: Can't get object clsid from progid
dll导出时候没有根据步骤1.3导出(我觉得大概率是dll属性中没勾选为COM互操作注册)