java使用JInvoke调用windows API
使用jinvoke调用windowsAPI。jna使用比较麻烦,需要写c代码和参数转换,jinvoke的使用就像jdk中的包一样。
官网使用参考:http://www.jinvoke.com/calling-the-win32-api-from-java
一个弹出框的例子(这种代码用于调用任何dll,不只是windows的,也可以是自己写的dll)
import com.jinvoke.JInvoke;
import com.jinvoke.NativeImport;
public class HelloWindows
{
@NativeImport(library="User32")
public static native int MessageBox(int hwnd,
String text,
String caption,
int type); //windows Api MessageBox函数原型
public static void main(String[]argc)
{
JInvoke.initialize();
MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox",
"Hellow World",0);
}
}
运行效果:
使用以上代码方式可以任意调用本地的DLL文件。
注意:1.import com.jinvoke.JInvoke;import com.jinvoke.NativeImport;//引用包
2.@NativeImport(library="User32")//指定本地的DLL文件
3.public static native int MessageBox(int hwnd,String text,String caption,int type); //windows Api MessageBox函数原型 声明一个可以在java当前类中使用的方法
4.JInvoke.initialize();//实例化JInvoke
5.MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox","Hellow World",0);//然后就可以开始调用DLL中的函数了
如果只是为了使用User32.dll中的函数可以直接使用jinvoke.jar中提供的User32类,而不必使用@NativeImport(library="User32")去包含一个DLL,再去声明一个做函数的类型转换的方法。
编译是需要带上jinvoke.jar即:java -classpath .;jinvoke.jar HelloWindows
========
Java 调用 Windows API 可能性的实现
在 Google 输入 java call win32api 的第一个结果
http://www.jinvoke.com/calling-the-win32-api-from-java
看看这个吧
java版任务管理器
java版注册表编辑器
Calling the Win32 API from Java
首先从 http://www.jinvoke.com/calling-the-win32-api-from-java 将 jinvoke下载回来
将 jinvoke.jar 解压到 磁盘任意目录,配置环境变量
如果当前用户中没有 classpath 环境变量 请新建之
我这里 java 安装路径是 C:/Program Files/Java/jdk1.5.0_09
我应该设置的的 classpath 值是
.;C:/Program Files/Java/jdk1.5.0_09/lib/tools.jar;C:/Program Files/Java/jdk1.5.0_09/lib/dt.jar
其中 .; 代表当前目录
其次查看 系统全局变量“系统变量”
找到path
在path头处添加 .;
尾部添加;C:/Program Files/Java/jdk1.5.0_09/bin;
配置好后一路“确定”后编写java文件
import com.jinvoke.JInvoke;
import com.jinvoke.NativeImport;
public class HelloWindows
{
@NativeImport(library="User32")
public static native int MessageBox(int hwnd,
String text,
String caption,
int type); //windows Api MessageBox函数原型
public static void main(String[]argc)
{
JInvoke.initialize();
MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox",
"Hellow World",0);
}
}
将 jinvoke.jar 放到 HelloWindows.java 同级目录
统计目录编写批处理文件 compile.bat
@echo off
color 0f
javac -classpath %~dp1jinvoke.jar; %1
if %errorlevel%==0 (
echo 编译成功
cd %~dp1
java -classpath %~dp1jinvoke.jar; %~n1>nul 2>nul
)
pause
把 HelloWindows.java 往 complie.bat 拖动
如果你的java软件包没问题就会出现这个画面
csdn 示例下载地址
http://download.csdn.net/source/1623746
========
Java学习笔记 Java调用Win32 API控制鼠标活动范围
今天学习Java看到Jni部分, 终于看到Java如何调用其他语言写的函数
首先是Java写的测试类
public class TestJni
{
native void SetMouseRangle(int left, int right, int top, int bottom);
static{
System.loadLibrary("TestJni");
}
public static void main(String []args){
TestJni test = new TestJni();
test.SetMouseRangle(0,0,0,0);
test.SetMouseRangle(100,100,200,200);
}
}
SetMouseRangle用它来代替同名的本地函数,它的前面必须要有native关键字,而且它不能有函数体.这个函数是为了指定一个矩形的范围,把鼠标限定在这个矩形里面5秒钟.
static{
System.loadLibrary("TestJni");
}
是为了加载TestJni.dll的(在其他平台上动态库的后缀名不为dll,这里由系统自己判断后缀名是dll还是os等),本地的SetMouseRangle就放在这个动态库中.
然后用javac生成class文件.用,javah生成c语言的头文件.
然后打开C++编译器,新建一个win32动态链接库项目.把生成的TestJni.h头文件包含进去就行了.
然后 #include"TestJni.h"
创建一个导出函数
JNIEXPORT void JNICALL Java_TestJni_SetMouseRangle
(JNIEnv *, jobject, jint left, jint right, jint top, jint bottom)
{
RECT rect;
rect.left = left;
rect.right = right;
rect.top = top;
rect.bottom = bottom;
ClipCursor(&rect);
Sleep(5000);
ClipCursor(0);
}
ClipCursor为一个Win32 API函数,作用是把鼠标限定在传入的矩形范围内.最后要调用ClipCursor(0);
否则鼠标将一直被限定在那个矩形范围内.
然后编译,在这里处了点问题,提示找不到Jni.h,想到一个笨办法,把Jni.h的目录附加进来.我的
Jni.h所在目录为C:/Program Files/Java/jdk1.6.0/include,还要把一个目录附加进来,因为还会用到C:/Program Files/Java/jdk1.6.0/include/win32这个目录中的头文件
然后编译,将生成的dll拷贝到class所在目录,如果名字不为TestJni.dll就把它改为这个名字,就可以运行了.
========
说明如何从 Java 调用 Win32API JWindow
点击这里察看该文章的英文版: 177162
概要
JWINDOW 示例阐释如何从 Java 应用程序调用 Win32API。 该示例包含单个类调用 JWindow, 基本上通过使用 Win 32 API CreateWindow 创建窗口并显示 " Hello JWindow " 在工作区通过处理 WM _ PAINT WndProc 中。 此示例阐释如何使用 @ dll.import 指令来调用 Win32DLL 函数从 Java、 回调和嵌套结构类型。
更多信息
可用于从 Microsoft 下载中心下载下列文件:
Jwindow.exe
有关如何下载 Microsoft 支持文件请单击下列文章编号以查看 Microsoft 知识库中相应:
119591 如何从联机服务获取 Microsoft 支持文件
此文件进行病毒扫描 Microsoft。 Microsoft 使用最新病毒检测软件, 投递文件日期上的可用。 文件存储, 有助于防止对文件进行任何未经授权更改安全性增强的服务器上。
该 JWINDOW 示例包含 JWindow.java, 它调用标准 Win32DLL 并阐释如何使用 @ dll.import 指令来调用 DLL 函数从 Java。
要使用 J/Direct, 您需要安装 1.02.4337 版本或更高的 Microsoft 编译器 for Java (Jvc.exe) 和 Microsoft 虚拟机 for Java 2252 或更高版本。 编译器就用 Microsoft SDK for Java 2.0 x 或更高版本。 虚拟机, 但是, SDK for Java 附带 3.2 和以后, 版本中已不再并且必须下载 seperately。 有关详细信息, 请访问以下 Microsoft 网站:
http://www.microsoft.com/mscorp/java/
站点。
当执行 Java 应用程序, 如果遇到一个 UnsatisifiedLinkError, 然后检查您的编译器版本。 如果编译器不支持 J/Direct, MicrosoftWin 虚拟机将试图链接本机方法使用原始本机接口, 因此不会成功。
参考
支持有关 VisualJ++ 和 SDKforJava, 请访问以下 MicrosoftWeb 站点获取:
http://www.microsoft.com/java
Warning: This article has been translated automatically
========
Java中调用Windows API的方法
要在Java中调用Windows API,最简单的方法就是使用JNative.jar中提供的接口。该库已经对Linux和Windows系统中的API进行了封装,例如对Windows,使用它里面的接口调用就和在Delphi等开发工具中的调用方法是一样的,因为函数的名字和参数都是一样的。下面说明其用法。
安装方法:将JNative.jar加到classpath中即可。
假如现在要给QQ的窗口发送消息,程序如下:
import org.junit.Test;
import org.xvolks.jnative.misc.basicStructures.HWND;
import org.xvolks.jnative.misc.basicStructures.LPARAM;
import org.xvolks.jnative.misc.basicStructures.UINT;
import org.xvolks.jnative.misc.basicStructures.WPARAM;
import org.xvolks.jnative.util.User32;
public class JNativeLearning {
@Test
public void sendMessage() throws Exception {
HWND hWnd=User32.FindWindow("TXGuiFoundation", "QQ2010");
if(hWnd.getValue()>0){
System.out.println("窗口存在");
User32.SendMessage(hWnd, new UINT(0x10), new WPARAM(0), new LPARAM(0));
}else{
System.out.println("窗口不存在");
}
}
}
其它接口请参见其JavaDoc:http://jnative.free.fr/docs/
========
Java调用C/C++ API 讲解及代码示例
JAVA
我们知道Java是一种平台无关性的语言,平台对于上层的java代码来说是透明的,所以在多数时间我们是不需要调用本地方法,但是假如你遇到了以下情况,你可能就需要使用Java调用本地方法了:
你的Java代码需要得到一个文件的属性。但是你找遍了JDK帮助文档也找不到相关的API。
在本地还有一个别的系统,不过它不是Java语言实现的,这个时候你需要把两套系统整合到一起。
你的Java代码中需要用到某种算法,不过算法是用C实现并封装在动态链接库文件(DLL)当中的。
对于上述的三种情况,如果没有JNI的话,那就会变得异常棘手了。JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。
在Java中有一些native方法,这些方法只有方法签名但是没有方法体。其实这些naive方法就是我们说的 java native interface。它提供了一个调用(invoke)的接口,然后用C或者C++去实现。
JNI概述
JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,它是一种双向的接口,使得开发者可以通过Java代码调用到各种native的库,反之亦然。所以JNI(Java Native Interface)能作为Java语言的一部分,她能够作为粘合剂将Java应用和其他本地应用(C/C++,Delphi)集合在一起。
作为一个双向的接口,JNI能支持两种native代码:native libraries 和native applications。
你能使用JNI去写一些native methods去允许Java Applications能呼叫native libraries中的函数,native methods的具体实现是可能C,C++或者Delphi。
JNI也支持嵌入一个JVM实现到一个本地应用程序中去,去执行那些用Java语言编写的的模块.比如,一个C++编写的浏览器利用内嵌的JVM去执行下载到本地的applet。
实现步骤:
1) 完成Java代码,编写好Java调用类。
2) 编译你的Java类。
3) 用javah生成编译好的class文件对应的C/C++ 函数的头文件。
4) 实现头文件中的函数原型,编写native代码。
5) 将native代码编译打包成DLL库(win32)或共享库(Linux)。
6) 将你的Java代码跑起来
例子
1. 编写Java代码。
注意:
(1) 调用本地代码的java方法,要设置成native的。
(2) 要使用System的LoadLibrary方法去加载包含本地方法实现的库。
package eric.test;
public class JNITest {
static {
System.loadLibrary("JNITest");
}
public static native void sayHelloWorld(String msg);
public static void main(String[] args) {
sayHelloWorld("Hello, world");
}
}
2. 编译生成的class文件:JNITest.class
3. 在命令行下使用javah生成C/C++头文件。在工程的bin目录下输入以下命令:
Cmd代码:
javah -classpath . -jni eric.test.JNITest
将生成头文件eric_test_JNITest.h,内容如下:
Cpp代码:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class eric_test_JNITest */
#ifndef _Included_eric_test_JNITest
#define _Included_eric_test_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: eric_test_JNITest
* Method: sayHelloWorld
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_eric_test_JNITest_sayHelloWorld
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
注意,在执行javah的时候,要输入完整的包名和类名。否则在以后的测试调用过程中会发生java.lang.UnsatisfiedLinkError这个异常。
4. 实现C++代码。在VS2008中创建一个Win32 project,类型为DLL。
将刚才生成的头文件eric_test_JNITest.h拷到工程目录下,并且在项目中导入到Header Files里面。打开StdAfx.h文件,在最后面添加:
#include "jni.h"
#include "eric_test_JNITest.h"
打开JNITest.cpp文件,在其中添加实现代码。函数名为头文件中定义的函数声明。
#include
using namespace std;
JNIEXPORT void JNICALL Java_eric_test_JNITest_sayHelloWorld
(JNIEnv* env, jclass method, jstring param)
{
const char* pt = env->GetStringUTFChars(param, 0);
cout << pt << " called by Java Native Interface" << endl;
}
其中,GetStringUTFChars是jre中提供的jni方法,用来得到java string的字符串。
5. 构建C++项目。会出现"Cannot open include file: 'jni.h': No such file or directory"的错误,解决方法是将以下文件拷贝到C++工程目录下
%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\win32\jni_md.h
同时将头文件eric_test_JNITest.h中的 #include 改为
01.#include "jni.h"
然后重新build,将在debug目录下生成JNITest.dll文件。
6. 将dll文件复制到Java工程的bin目录下(这个位置十分重要,否则会出现not found的异常),并运行程序
java eric.test.JNITest
将输出结果"Hello, world called by Java Native Interface"。
========
jni java调用win32 dll的方法
1 在java中写好java需要的win32 dll中需要的函数说明 ,并编译成功
2 在win32 的cmd中,到java文件所在的目录(eg: d:\java\isoline\com\util)下,调用命令:
1)javac objectiveAnalyse.java 此时成功后,会在目录d:\java\isoline\com\util下生成objectiveAnalyse.class文件
(2) cmd转当前目录到d:\java\isoline javah -jni com.util.objectiveAnalyse ,即可生成c++ dll所需要的com_util_objectiveAnalyse.h文件
3 此时 会在当前目录下生成java需要的com_util_objectiveAnalyse.h文件,文件中产生了函数Java_PictureFactoryPlugin_GetDataPicture()
4 手工改成java需要的包结构,如java需要 com_util 包结构,则改为:Java_com_util_PictureFactoryPlugin_GetDataPicture()
5 在cpp文件中实现:Java_com_util_PictureFactoryPlugin_GetDataPicture() 的功能即可。
6 生成win32 dll ,就可以被java调用 了
========
使用 J-Interop 在 Java 中调用WMI
有关WMI的小知识
Windows管理规范(WMI)是微软对来自分布式管理任务组(DMTF)的基于Web的企业管理(WBEM)和通用信息模型(CIM)标准的实现。WMI用于访问Windows系统、应用、网络、设备等组件,并管理它们。连接到一台机器通过DCOM进行管理。因此,有关DCOM的小知识将有助于本文的理解。你可以到MSDN了解有关WMI的更多细节。
J-Interop
市场上有一些在使用 JAVA 调用 WMI 的好库,包括 J-Interop、JACOB-Project 和 J-Integra。其中,我更喜欢J-Interop,因为它是完全免费和开源的API。它提供了没有任何依赖的纯DCOM桥,完全用Java编写的没有任何JNI代码。
使用WMI管理Windows服务
现在,来看一个使用JAVA调用WMI的例子。这个例子利用J-Interop的API使用Win32_Service类解释WMI操作,将启动和停止在这个例子中的窗口服务。
步骤1:连接到WBEM服务
下面的代码示例显示了使用J-Interop如何初始化DCOM会话,并连接到远程DCOM服务使。它使用SWbemLocator对象连接到SWbemServices,SWbemServices对象提供对本地或远程计算机WMI的访问,它调用“ConnectServer”方法连接到SWbemServices。在本例中,提供管理员级别的用户连接到远程计算机。
JISessiondcomSession=JISession.createSession(domainName,userName,password);
dcomSession.useSessionSecurity(false);
JIComServercomServer=newJIComServer(valueOf("WbemScripting.SWbemLocator"),hostIP,dcomSession);
IJIDispatchwbemLocator=(IJIDispatch)narrowObject(comServer.createInstance().queryInterface(IID));
//parameterstoconnecttoWbemScripting.SWbemLocator
Object[]params=newObject[]{
newJIString(hostIP),//strServer
newJIString(win32_namespace),//strNamespace
JIVariant.OPTIONAL_PARAM(),//strUser
JIVariant.OPTIONAL_PARAM(),//strPassword
JIVariant.OPTIONAL_PARAM(),//strLocale
JIVariant.OPTIONAL_PARAM(),//strAuthority
newInteger(0),//iSecurityFlags
JIVariant.OPTIONAL_PARAM()//objwbemNamedValueSet
};
JIVariantresults[]=wbemLocator.callMethodA("ConnectServer",params);
IJIDispatchwbemServices=(IJIDispatch)narrowObject(results[0].getObjectAsComObject());
(domainName=远程计算机域名,hostIP=远程计算机IP地址,用户名=管理员级别的用户,密码=密码)
第2步:获取Win32_Service实例
一旦你获得对SWbemServices对象的引用,就可以调用这个类的任何方法。其中WbemServices.InstancesOf方法获得任何Win32类的实例。
也可以使用WMI查询语言(WQL)达到同样的目的,如下所示:
finalintRETURN_IMMEDIATE=0x10;
finalintFORWARD_ONLY=0x20;
Object[]params=newObject[]{
newJIString("SELECT*FROMWin32_Service"),
JIVariant.OPTIONAL_PARAM(),
newJIVariant(newInteger(RETURN_IMMEDIATE+FORWARD_ONLY))
};
JIVariant[]servicesSet=wbemServices.callMethodA("ExecQuery",params);
IJIDispatchwbemObjectSet=(IJIDispatch)narrowObject(servicesSet[0].getObjectAsComObject());
第三步:执行方法
现在,已得到Win32_Service类的实例,可采用下述代码来调用同一类的方法,因为,它返回多个服务实例,要列举它们以便获取IJIDispatcher服务。
JIVariant newEnumvariant = wbemObjectSet.get("_NewEnum");
IJIComObject enumComObject = newEnumvariant.getObjectAsComObject();
IJIEnumVariant enumVariant = (IJIEnumVariant) narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));
Object[] elements = enumVariant.next(1);
JIArray aJIArray = (JIArray) elements[0];
JIVariant[] array = (JIVariant[]) aJIArray.getArrayInstance();
for (JIVariant variant : array) {
IJIDispatch wbemObjectDispatch = (IJIDispatch) narrowObject(variant.getObjectAsComObject());
JIVariant returnStatus = wbemObjectDispatch.callMethodA("StopService");
System.out.println(returnStatus.getObjectAsInt());
}
现在,下面的代码显示了一个使用WMI启动和停止Windows服务的完整Java类。
packagecom.wmi.windows;
importstaticorg.jinterop.dcom.core.JIProgId.valueOf;
importstaticorg.jinterop.dcom.impls.JIObjectFactory.narrowObject;
importstaticorg.jinterop.dcom.impls.automation.IJIDispatch.IID;
importjava.util.logging.Level;
importorg.jinterop.dcom.common.JIException;
importorg.jinterop.dcom.common.JIRuntimeException;
importorg.jinterop.dcom.common.JISystem;
importorg.jinterop.dcom.core.IJIComObject;
importorg.jinterop.dcom.core.JIArray;
importorg.jinterop.dcom.core.JIComServer;
importorg.jinterop.dcom.core.JISession;
importorg.jinterop.dcom.core.JIString;
importorg.jinterop.dcom.core.JIVariant;
importorg.jinterop.dcom.impls.automation.IJIDispatch;
importorg.jinterop.dcom.impls.automation.IJIEnumVariant;
publicclassServiceManager{
privatestaticStringdomainName="";
privatestaticStringuserName="administrator";
privatestaticStringpassword="";
privatestaticStringhostIP="127.0.0.1";
privatestaticfinalStringwin32_namespace="ROOT\\CIMV2";
privatestaticfinalintSTOP_SERVICE=0;
privatestaticfinalintSTART_SERVICE=1;
privateJISessiondcomSession=null;
publicstaticvoidmain(String[]args){
ServiceManagermanager=newServiceManager();
manager.stopService(domainName,hostIP,userName,password,"MySql");//stopsaservicenamedMySql
}
publicvoidstartService(StringdomainName,Stringhostname,Stringusername,Stringpassword,StringserviceName){
execute(domainName,hostname,username,password,serviceName,START_SERVICE);
}
publicvoidstopService(StringdomainName,Stringhostname,Stringusername,Stringpassword,StringserviceName){
execute(domainName,hostname,username,password,serviceName,STOP_SERVICE);
}
publicvoidexecute(StringdomainName,Stringhostname,Stringusername,Stringpassword,StringserviceName,intaction){
try{
IJIDispatchwbemServices=createCOMServer();
finalintRETURN_IMMEDIATE=0x10;
finalintFORWARD_ONLY=0x20;
Object[]params=newObject[]{
newJIString("SELECT*FROMWin32_ServiceWHEREName='"+serviceName+"'"),
JIVariant.OPTIONAL_PARAM(),
newJIVariant(newInteger(RETURN_IMMEDIATE+FORWARD_ONLY))
};
JIVariant[]servicesSet=wbemServices.callMethodA("ExecQuery",params);
IJIDispatchwbemObjectSet=(IJIDispatch)narrowObject(servicesSet[0].getObjectAsComObject());
JIVariantnewEnumvariant=wbemObjectSet.get("_NewEnum");
IJIComObjectenumComObject=newEnumvariant.getObjectAsComObject();
IJIEnumVariantenumVariant=(IJIEnumVariant)narrowObject(enumComObject.queryInterface(IJIEnumVariant.IID));
Object[]elements=enumVariant.next(1);
JIArrayaJIArray=(JIArray)elements[0];
JIVariant[]array=(JIVariant[])aJIArray.getArrayInstance();
for(JIVariantvariant:array){
IJIDispatchwbemObjectDispatch=(IJIDispatch)narrowObject(variant.getObjectAsComObject());
//Printobjectastext.
JIVariant[]v=wbemObjectDispatch.callMethodA("GetObjectText_",newObject[]{1});
========
java 调用user32.dll 锁定电脑
public interface Kernel32 extends Library {
public boolean Beep(int FREQUENCY, int DURATION);
public void Sleep(int DURATION);
}
public interface User32 extends Library {
boolean LockWorkStation();
}
public static void main(String[] args) {
Kernel32 lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
lib.Beep(698, 1500);
lib.Sleep(500);
lib.Beep(698, 500);
User32 dll = (User32) Native.loadLibrary("user32", User32.class);
dll.LockWorkStation();
}
========
java调用.dll文件
一.在程序用jnative调用window的dll
1. 安装
http://sourceforge.net/projects/jnative
解压后得到3个文件:JNativeCpp.dll,libJNativeCpp.so,JNative.jar,其中:
JNativeCpp.dll 放在windows/system32目录下
libJNativeCpp.so linux下使用
JNative.jar 导入工程中
2. 使用
2.1. 加载dll文件
JNative可使用两种方式加载dll文件:
a.使用System.loadLibrary加载,使用此方法可加载系统目录中的dll文件。
b.可以先把dll文件复制到system32目录下,使用文件前缀名作为参数来加载dll文件。使用System.load加载,此方法参数为dll文件全路径名。
2.2. 调用函数
a、首先创建JNative对象:
JNative jnative = new JNative(dll文件名, 函数名);
b、设置返回值类型:
jnative.setRetVal(Type.INT);
c、设置参数
jnative.setParameter(0, Type.STRING, …); //设置第一个参数为字符串
jnative.setParameter(1, Type.INT, String.valueof(…)); //设置第二个参数为整数
d、执行
n.invoke();
e、获取返回值
Integer.parseInt(jnative.getRetVal());
3.实例
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.HeapMemoryBlock;
public class Test {
public static void main(String[] args) throws NativeException, IllegalAccessException {
JNative v=new JNative("Kernel32.dll","GetModuleFileNameA");
int i = 0;
v.setRetVal(Type.INT);
Pointer pName = new Pointer(new HeapMemoryBlock(1024));
v.setParameter(i++, 0);//module handle
v.setParameter(i++, pName);//pFileName
v.setParameter(i++, 1024);//nSize
v.setRetVal(Type.INT);
v.invoke();
int ret = Integer.parseInt(v.getRetVal());
if (ret == 0) {
// return "null";
System.err.println(
"GetModuleFileName failed!");
} else {
String path = pName.getAsString().substring(0,
ret);
pName.dispose();
v.dispose();
System.out.println("current process's path is:"+path);
}
}
}
4.注意:
在JNative中用了JDK1.5的一些特性,如枚举、静态引入等,所以在JDK1.4下是不能用的。
二.在程序用jawin调用window的dll
jawin 可以对dll中的方法进行调用,也可以调用com中的方法.内部还提供了一个工具,直接对 com组件导出成 java的类,个人认为很方便。
下面是我们作的一个测试,很顺利便通过了。
1、下载jawin:http://jawinproject.sourceforge.net/。
2、配置:
a.将jawin.jar放于%JAVA_HOME%/jre/lib/ext下 。
b.将jawin.dll放于c:/winnt/system32下。否则将出现错误:COMException : no jawin in java.library.path;
也可将jawin.dll放于每个项目目录下。
c.至此在Editplus中调试Jawin/NJawin的例子,可以通过。 而在Eclipse中有时还会出上面的错误:COMException : no jawin in java.library.path。
d.在Eclipse中,菜单->window->preference->Java->installed JREs 将原来的remove,重新建一个指到你的java sdk目录。 ok了。
3、程序测试:
import org.jawin.FuncPtr;
import org.jawin.ReturnFlags;
public class GfJawinTest {
public static void main(String[] args) {
try {
FuncPtr msgBox = new FuncPtr("USER32.DLL", "MessageBoxW");
msgBox.invoke_I(0, "Hello From a DLL", "From Jawin", 0, ReturnFlags.CHECK_NONE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.利用jawin调用com组件, 如word:
//创建word
import org.jawin.DispatchPtr;
import org.jawin.win32.Ole32;
public class CreateWord {
public static void main(String[] args) {
try {
Ole32.CoInitialize();// 初始化
DispatchPtr app = new DispatchPtr("Word.Application");// 创建word对象
app.put("Visible",true); // 使word可见
DispatchPtr docs=(DispatchPtr)app.get("Documents"); // 获得document对象集合
DispatchPtr doc=(DispatchPtr)docs.invoke("Add"); // 新增一个文档
app.invoke("Activate"); // 激活当前文档
DispatchPtr objTextFont=(DispatchPtr)((DispatchPtr)doc.get("Content")).get("Font");
// 取得Font对象
objTextFont.put("Name","黑体");
// 设置字体
objTextFont.put("Size","48");
// 设置字号
DispatchPtr docSelection=(DispatchPtr)app.get("Selection");
// 取得Selection对象
docSelection.invoke("TypeText","Jawwintesttext!/nJawin测试文本。");
// 使用TypeText方法添加文本
doc.invoke("SaveAs","d://jawintest.doc");
// 保存文档(保存在C盘根目录下)
doc.invoke("Close");
// 关闭当前文档,去掉前面的注释符并重新编译后可生效
app.invoke("Quit");
// 退出Word,去掉前面的注释符并重新编译后可生效
Ole32.CoUninitialize(); // 释放对象
} catch (Exception e) {
e.printStackTrace();
}
}
}
//打开word
import org.jawin.DispatchPtr;
import org.jawin.win32.Ole32;
public class OpenWord {
public static void main(String[] args) {
try {
Ole32.CoInitialize();
DispatchPtr app = new DispatchPtr("Word.Application");
app.put("Visible", true);
DispatchPtr docs = (DispatchPtr) app.get("Documents");
DispatchPtr doc = (DispatchPtr) docs.invoke("Open", "d://word.doc");
Ole32.CoUninitialize();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//调用word中的另存为,保存为.html
import org.jawin.DispatchPtr;
import org.jawin.win32.Ole32;
public class Word2Html {
public static void main(String[] args) {
String path = "e://17001939578.doc";
int iPos = path.lastIndexOf(".");
String fileExtName = path.substring(iPos + 1);
String fileMainName = path.substring(0, iPos);
fileExtName = fileExtName.toLowerCase();
try {
Ole32.CoInitialize();
// 初始化
DispatchPtr app = new DispatchPtr("Word.Application");
// 创建word对象
app.put("Visible", false);
// 设置word不可见
DispatchPtr docs = (DispatchPtr) app.get("Documents");
// 取得Documents对象
DispatchPtr doc = (DispatchPtr) docs.invoke("Open", path);
// 打开指定的word文件
doc.invoke("SaveAs", fileMainName + ".html");
// 另存为HTML文件
app.invoke("quit");
// 关闭word
Ole32.CoUninitialize();
// 释放对象
System.out.println("/n转换完成!");
System.out.println("/n文件名:" + fileMainName + ".html");
} catch (Exception e) {
System.out.println("/n该文件不存在!或者其他错误(如:运行环境问题)!");
}
}
}
========
12 其他链接
http://www.cnblogs.com/cy163/category/223619.html
最近在做实验希望实现基于JNI技术在Java中使用 Slex.dll
Calling C Library Routines from Java
使用 SWIG 实现 Java 调用 C++ DLL
一种实现 Java调用C++的DLL的方法