jacob异常ComFailException: Can't map name to dispid

2020-05-19 09:38:19 | 编辑

1.案发现场

java使用jacob调用com组件操作office和word,总是出现下面问题

com.jacob.com.ComFailException: Can't map name to dispid: Open
	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.call(Dispatch.java:541)
	at com.xz.datacenter.ecg.word2pdf.util.COMManager.word2pdf(COMManager.java:81)
	at com.xz.datacenter.ecg.word2pdf.action.TestController$1.run(TestController.java:34)
	at java.lang.Thread.run(Thread.java:748)

加了代码ComThread.Release()后又出现下面问题

java.lang.IllegalStateException: Dispatch not hooked to windows memory

2.异常原因

com.jacob.com.ComFailException: Can’t map name to dispid: Open

这种异常是因为操作完成后,没有调用ComThread.Release()去释放jacob

java.lang.IllegalStateException: Dispatch not hooked to windows memory
这种异常有可能是多次调用了ComThread.Release();而引起的。

3.解决方法

单线程调用一般是不会出现问题的,出问题一般都是多线程调用,参考:JACOB调用COM组件的多线程问题

解决方法也很简单,我们要根据合理的调用ComThread.InitMTA()和ComThread.Release()。

关于ComThread.InitSTA()和ComThread.InitMTA()的区别,仍需要看完上面这篇文章。

下面这个案例我调用了两次ComThread.InitMTA(),然后在其他线程调用都美问题(初始化ActiveXComponent很耗时,一次初始化多次调用是解决性能问题)。

ComThread.startMainSTA();
for(int i=1;i<=5;i++){
	new Thread(new Runnable() {
		@Override
		public void run() {
			ComThread.InitMTA(true);
			ActiveXComponent app = new ActiveXComponent("Word.Application");
			app.setProperty("Visible", new Variant(false));
			app.setProperty("DisplayAlerts", new Variant(false));
			//初始化后放入到另外一个静态数组,方便其他线程使用调用
			COMSessionFactory.sessionPool.push(app);
			


		}
	}).start();

}

 

登录后即可回复 登录 | 注册
    
关注编程学问公众号