java 调用win32 api 学习总结

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的方法

你可能感兴趣的:(转载,Java)