最近公司在做一个项目中有需要调用远程视频监控的部分。
远程的视频服务器是由第三方公司开发的,他们提供了ocx控件用于做开发调用。在Javascript已经实现调用,远程视频可以调用出来。
但是在js中调用,每台客户机就都得下载安装ocx控件(当然这样也可以)。想要实现的是在服务器端安装ocx控件,由服务器端的java后台程序去调用ocx控件对远端视频服务器进行操作,
这样客户端机器上就不用每台机器都安装ocx控件了。(想法是这样的)如是开始寻找java中调用ocx控件的办法方法,jni、jacob....但是试验下来发现调用像word、excel这些ActiveX控件是可以的,操作没有问题,换作视频的ocx控件就不能调用了。
请各位来帮忙解决解决。JavaScript下调用的代码如下:(这种方式是Ok的)<HTML>
<HEAD>
<TITLE>视频调用</TITLE>
<script language="javascript" for="NVS5000" event="OnLoginNVSResult(nResult)">
//ocx对象的OnLoginNVSResult事件触发时
OnLoginNVS(nResult);
</script>
<script type="text/javascript" language="javascript">
function $()
{
var elements = new Array();
for (var i = 0; i < arguments.length; i++)
{
var element = arguments[i];
if (typeof element == 'string')
{
element = document.getElementById(element);
}
if (arguments.length == 1)
{
return element;
}
elements.push(element);
}
return elements;
}
//初始化方法
function init()
{
try{
//为ocx对象属性赋值
$("NVS5000").URL = "192.168.15.153"; //前端设备地址
$("NVS5000").Port = 5200; //端口号
$("NVS5000").NVSName = "NVS";
$("NVS5000").UserName = "admin"; //用户名
$("NVS5000").UserPswd = "admin"; //密码
$("NVS5000").SetLoginMode(1); //设置登录模式
$("NVS5000").Tips_Off();
$("NVS5000").AlarmBox_Off();
$("NVS5000").FullWnd_Off();
$("NVS5000").SocketProtocol=0; //设置套接字协议
$("NVS5000").ChannelNum= 0; //频道号
//登录前端设备
$("NVS5000").LoginNVS();
//浏览器状态显示
window.status = $("NVS5000").URL+":"+$("NVS5000").Port+" , Account:"+$("NVS5000").UserName+"/"+$("NVS5000").UserPswd;
}catch(e){}
}
//登录时触发方法
function OnLoginNVS(nResult)
{
try{
if(nResult < 2)
{
switch(nResult)
{
case -1:
window.status = " 操作失败!";
break;
case -2:
window.status = " 请求被拒绝!";
break;
case -3:
window.status = " 登录用户已满!";
break;
case -4:
window.status = " 用户名或密码和系统不匹配!";
break;
case -5:
window.status = " 已经关闭IE!";
break;
case -6:
window.status = " 连接DDNS失败!";
break;
case -7:
window.status = " 获取设备信息失败!";
break;
default:
window.status = " 其他未知错误! " + nResult;
break;
}
return false;
}else{
//启动视频
$("NVS5000").StartView();
}
}catch(e){}
}
</script></HEAD>
<BODY onLoad="init()">
<object name="NVS5000" ID="NVS5000" width="705" height="570"
CLASSID="CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A">
</object>
</BODY>
</HTML>
尝试在Java下使用jacob调用的代码如下:package com.mdbq.jni;import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class XDViewDemo
{
public static void main(String[] args)
{
//初始化线程
ComThread.InitSTA();
ActiveXComponent activeX = new ActiveXComponent("CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A");
Dispatch NVS5000 = (Dispatch)activeX.getObject();
Variant result = Dispatch.call(NVS5000,"LoginNVS","");
//释放线程
ComThread.Release();
}
}
出错语句在:Variant result = Dispatch.call(NVS5000,"LoginNVS","");
(只要是调用ocx的方法就会出错。)eclipse控制台下的错误如下:Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: LoginNVS
Description: 灾难性故障 at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:858)
at com.jacob.com.Dispatch.callN(Dispatch.java:455)
at com.jacob.com.Dispatch.call(Dispatch.java:544)
at com.mdbq.jni.XDViewDemo.main(XDViewDemo.java:18)
请各位大大帮忙看看是什么问题?
远程的视频服务器是由第三方公司开发的,他们提供了ocx控件用于做开发调用。在Javascript已经实现调用,远程视频可以调用出来。
但是在js中调用,每台客户机就都得下载安装ocx控件(当然这样也可以)。想要实现的是在服务器端安装ocx控件,由服务器端的java后台程序去调用ocx控件对远端视频服务器进行操作,
这样客户端机器上就不用每台机器都安装ocx控件了。(想法是这样的)如是开始寻找java中调用ocx控件的办法方法,jni、jacob....但是试验下来发现调用像word、excel这些ActiveX控件是可以的,操作没有问题,换作视频的ocx控件就不能调用了。
请各位来帮忙解决解决。JavaScript下调用的代码如下:(这种方式是Ok的)<HTML>
<HEAD>
<TITLE>视频调用</TITLE>
<script language="javascript" for="NVS5000" event="OnLoginNVSResult(nResult)">
//ocx对象的OnLoginNVSResult事件触发时
OnLoginNVS(nResult);
</script>
<script type="text/javascript" language="javascript">
function $()
{
var elements = new Array();
for (var i = 0; i < arguments.length; i++)
{
var element = arguments[i];
if (typeof element == 'string')
{
element = document.getElementById(element);
}
if (arguments.length == 1)
{
return element;
}
elements.push(element);
}
return elements;
}
//初始化方法
function init()
{
try{
//为ocx对象属性赋值
$("NVS5000").URL = "192.168.15.153"; //前端设备地址
$("NVS5000").Port = 5200; //端口号
$("NVS5000").NVSName = "NVS";
$("NVS5000").UserName = "admin"; //用户名
$("NVS5000").UserPswd = "admin"; //密码
$("NVS5000").SetLoginMode(1); //设置登录模式
$("NVS5000").Tips_Off();
$("NVS5000").AlarmBox_Off();
$("NVS5000").FullWnd_Off();
$("NVS5000").SocketProtocol=0; //设置套接字协议
$("NVS5000").ChannelNum= 0; //频道号
//登录前端设备
$("NVS5000").LoginNVS();
//浏览器状态显示
window.status = $("NVS5000").URL+":"+$("NVS5000").Port+" , Account:"+$("NVS5000").UserName+"/"+$("NVS5000").UserPswd;
}catch(e){}
}
//登录时触发方法
function OnLoginNVS(nResult)
{
try{
if(nResult < 2)
{
switch(nResult)
{
case -1:
window.status = " 操作失败!";
break;
case -2:
window.status = " 请求被拒绝!";
break;
case -3:
window.status = " 登录用户已满!";
break;
case -4:
window.status = " 用户名或密码和系统不匹配!";
break;
case -5:
window.status = " 已经关闭IE!";
break;
case -6:
window.status = " 连接DDNS失败!";
break;
case -7:
window.status = " 获取设备信息失败!";
break;
default:
window.status = " 其他未知错误! " + nResult;
break;
}
return false;
}else{
//启动视频
$("NVS5000").StartView();
}
}catch(e){}
}
</script></HEAD>
<BODY onLoad="init()">
<object name="NVS5000" ID="NVS5000" width="705" height="570"
CLASSID="CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A">
</object>
</BODY>
</HTML>
尝试在Java下使用jacob调用的代码如下:package com.mdbq.jni;import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class XDViewDemo
{
public static void main(String[] args)
{
//初始化线程
ComThread.InitSTA();
ActiveXComponent activeX = new ActiveXComponent("CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A");
Dispatch NVS5000 = (Dispatch)activeX.getObject();
Variant result = Dispatch.call(NVS5000,"LoginNVS","");
//释放线程
ComThread.Release();
}
}
出错语句在:Variant result = Dispatch.call(NVS5000,"LoginNVS","");
(只要是调用ocx的方法就会出错。)eclipse控制台下的错误如下:Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: LoginNVS
Description: 灾难性故障 at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:858)
at com.jacob.com.Dispatch.callN(Dispatch.java:455)
at com.jacob.com.Dispatch.call(Dispatch.java:544)
at com.mdbq.jni.XDViewDemo.main(XDViewDemo.java:18)
请各位大大帮忙看看是什么问题?
但是操作失败,不太明白。ocx控件在系统中已经注册,用js是可以操作成功的。在想,有没有可能是使用jacob来操作的ocx必须是使用某种语言开发的。想想也不应该啊。
BOOL CMyNameCtrl::IsInvokeAllowed (DISPID)
{
return TRUE;
}
调用的简单过程如下:1.下载jacob:http://sourceforge.net/projects/jacob-project/files/jacob-project/1.15-M4/;
2.将jacob-1.15-M4包中的jacob-1.15-M4-x86.dll复制到系统环境变量中,我放在sytem32目录中;(官方说:在x64位系统时,copy jacob-1.15-M4-x64.dll至syswow64目录,不过我尝试后发现在x64位系统中仍然还是使用jacob-1.15-M4-x86.dll有效);
3.copy需要调用的ocx到系统环境变量中,我放在system32目录中,并且注册ocx控件,注意:注册你的ocx时需要注意此ocx有木有依赖其它的文件,比如我的ocx厂家就需要一个.lic文件与ocx在同一目录;
复制和注册过程可以自己写一个批处理(.bat),我的批处理如下:@echo off
@echo 注册控件(32位系统)
set sys=%windir%\system32
copy jacob-1.15-M4-x86.dll %sys%
copy *****.ocx %sys%
copy *****.lic %sys%c:
cd\
cd %sys%
regsvr32 /s *****.ocx4.项目中导入jacob.jar包;
5.使用jacob api调用ocx;
Demo:import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class JacobDemo
{
private static ActiveXComponent activeX;//ActiveX控件对象
private static Dispatch dispath;//MS级别的调度对象
static
{
//创建ActiveX控件对象
//可以使用CLSID,也可以使用ProgID
activeX = new ActiveXComponent("CLSID:A71B53F3-562C-451E-9F92-DCF5B8852B6E");
//获得调度对象
dispath = activeX.getObject();
}
/**
* 登陆110报警服务器
* @param ip ip地址
* @param port 端口号
* @param clientType 客户端类别
* @param loginName 登陆中心名称,格式为:(分中心名称:操作员代码:操作员名称)
* @return -1:登陆失败;0 开始登陆;1,2 已登陆 ; 3,4 登陆中
*/
public int loginSvr(String ip,String port,int clientType,String loginName)
{
//登陆后返回值(默认为-1)
int result=-1;
if(!ip.isEmpty()&&!port.isEmpty())
{
//尝试登陆5次,每间隔1秒一次
for(int i=0;i<5;i++)
{
System.out.println("尝试第"+(i+1)+"次登陆.");
//调用控件的登陆函数
Variant loginVar =Dispatch.call(dispath, "Login", ip,port,clientType,loginName);
//给结果赋值
result= loginVar.getInt();
//如果登陆成功,跳出循环
if(result==1||result==2)
{
break;
}
else
{
//线程休眠1秒
try
{
Thread.sleep(1*1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
return result;
}
public static void main(String[] args)
{
JacobDemo demo = new JacobDemo();
int result = demo.loginSvr("192.168.1.174", "6986", 0x1000000, "江苏明道保全报警中心:mingdao:mingdao");
if(result==1||result==2)
{
System.out.println("登陆成功!");
}
}
}6.如果需要知道你的ocx控件注册后的CLSID,可以在注册表中搜索得出:
假设我的控件名称是abc.ocx,
打开注册表:运行regedit
Ctrl+F打开查找对话框,查找abc.ocx,会展开一个目录类似:{A71B53F3-562C-451E-9F92-DCF5B8852B6E}
这个目录名即是CLSID.大致过程就是这样,如果有需要后续再写博文给大伙分享.