java 调用win32 api 学习总结
生活随笔
收集整理的這篇文章主要介紹了
java 调用win32 api 学习总结
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
java使用JInvoke調(diào)用windows API
使用jinvoke調(diào)用windowsAPI。jna使用比較麻煩,需要寫c代碼和參數(shù)轉(zhuǎn)換,jinvoke的使用就像jdk中的包一樣。?
官網(wǎng)使用參考:http://www.jinvoke.com/calling-the-win32-api-from-java?
一個(gè)彈出框的例子(這種代碼用于調(diào)用任何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函數(shù)原型?
public static void main(String[]argc)?
{?
? ?JInvoke.initialize();?
? ?MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox",?
? ? ? "Hellow World",0);?
}?
}?
運(yùn)行效果:?
使用以上代碼方式可以任意調(diào)用本地的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函數(shù)原型 聲明一個(gè)可以在java當(dāng)前類中使用的方法
? ? 4.JInvoke.initialize();//實(shí)例化JInvoke?
? ?5.MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox","Hellow World",0);//然后就可以開始調(diào)用DLL中的函數(shù)了
?
如果只是為了使用User32.dll中的函數(shù)可以直接使用jinvoke.jar中提供的User32類,而不必使用@NativeImport(library="User32")去包含一個(gè)DLL,再去聲明一個(gè)做函數(shù)的類型轉(zhuǎn)換的方法。
?
編譯是需要帶上jinvoke.jar即:java -classpath .;jinvoke.jar HelloWindows?
========
Java 調(diào)用 Windows API 可能性的實(shí)現(xiàn)?
在 Google 輸入 java call win32api 的第一個(gè)結(jié)果
?
http://www.jinvoke.com/calling-the-win32-api-from-java
看看這個(gè)吧
?java版任務(wù)管理器
?java版注冊表編輯器
?
Calling the Win32 API from Java
?
首先從 http://www.jinvoke.com/calling-the-win32-api-from-java 將 jinvoke下載回來
?
將 jinvoke.jar 解壓到 磁盤任意目錄,配置環(huán)境變量
?
如果當(dāng)前用戶中沒有 classpath 環(huán)境變量 請新建之
?
我這里 java 安裝路徑是 C:/Program Files/Java/jdk1.5.0_09
?
我應(yīng)該設(shè)置的的 classpath 值是
?
.;C:/Program Files/Java/jdk1.5.0_09/lib/tools.jar;C:/Program Files/Java/jdk1.5.0_09/lib/dt.jar
?
其中 .; 代表當(dāng)前目錄
?
其次查看 系統(tǒng)全局變量“系統(tǒng)變量”
?
找到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函數(shù)原型 ?
??
public static void main(String[]argc) ?
{ ?
? ?JInvoke.initialize(); ?
? ?MessageBox(0,"Thisi MessageBox is a native Win32 MessageBox", ?
? ? ? "Hellow World",0); ?
} ?
} ?
?
將 jinvoke.jar 放到 HelloWindows.java 同級目錄
?
統(tǒng)計(jì)目錄編寫批處理文件 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軟件包沒問題就會出現(xiàn)這個(gè)畫面
csdn 示例下載地址
?
http://download.csdn.net/source/1623746
?
========
Java學(xué)習(xí)筆記 Java調(diào)用Win32 API控制鼠標(biāo)活動范圍?
今天學(xué)習(xí)Java看到Jni部分, 終于看到Java如何調(diào)用其他語言寫的函數(shù)
?
首先是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用它來代替同名的本地函數(shù),它的前面必須要有native關(guān)鍵字,而且它不能有函數(shù)體.這個(gè)函數(shù)是為了指定一個(gè)矩形的范圍,把鼠標(biāo)限定在這個(gè)矩形里面5秒鐘.
??
? ?static{?
? ? ?System.loadLibrary("TestJni");?
? ?}
?
是為了加載TestJni.dll的(在其他平臺上動態(tài)庫的后綴名不為dll,這里由系統(tǒng)自己判斷后綴名是dll還是os等),本地的SetMouseRangle就放在這個(gè)動態(tài)庫中.
?
然后用javac生成class文件.用,javah生成c語言的頭文件.
??
然后打開C++編譯器,新建一個(gè)win32動態(tài)鏈接庫項(xiàng)目.把生成的TestJni.h頭文件包含進(jìn)去就行了.
?
然后 #include"TestJni.h"?
創(chuàng)建一個(gè)導(dǎo)出函數(shù)
?
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為一個(gè)Win32 API函數(shù),作用是把鼠標(biāo)限定在傳入的矩形范圍內(nèi).最后要調(diào)用ClipCursor(0);
?
否則鼠標(biāo)將一直被限定在那個(gè)矩形范圍內(nèi).
?
然后編譯,在這里處了點(diǎn)問題,提示找不到Jni.h,想到一個(gè)笨辦法,把Jni.h的目錄附加進(jìn)來.我的
?
Jni.h所在目錄為C:/Program Files/Java/jdk1.6.0/include,還要把一個(gè)目錄附加進(jìn)來,因?yàn)檫€會用到C:/Program Files/Java/jdk1.6.0/include/win32這個(gè)目錄中的頭文件
?
然后編譯,將生成的dll拷貝到class所在目錄,如果名字不為TestJni.dll就把它改為這個(gè)名字,就可以運(yùn)行了.
?
========
說明如何從 Java 調(diào)用 Win32API JWindow?
點(diǎn)擊這里察看該文章的英文版: 177162
概要
?JWINDOW 示例闡釋如何從 Java 應(yīng)用程序調(diào)用 Win32API。 該示例包含單個(gè)類調(diào)用 JWindow, 基本上通過使用 Win 32 API CreateWindow 創(chuàng)建窗口并顯示 " Hello JWindow " 在工作區(qū)通過處理 WM _ PAINT WndProc 中。 此示例闡釋如何使用 @ dll.import 指令來調(diào)用 Win32DLL 函數(shù)從 Java、 回調(diào)和嵌套結(jié)構(gòu)類型。
更多信息
可用于從 Microsoft 下載中心下載下列文件:
Jwindow.exe
?有關(guān)如何下載 Microsoft 支持文件請單擊下列文章編號以查看 Microsoft 知識庫中相應(yīng):?
119591 如何從聯(lián)機(jī)服務(wù)獲取 Microsoft 支持文件?
此文件進(jìn)行病毒掃描 Microsoft。 Microsoft 使用最新病毒檢測軟件, 投遞文件日期上的可用。 文件存儲, 有助于防止對文件進(jìn)行任何未經(jīng)授權(quán)更改安全性增強(qiáng)的服務(wù)器上。
?該 JWINDOW 示例包含 JWindow.java, 它調(diào)用標(biāo)準(zhǔn) Win32DLL 并闡釋如何使用 @ dll.import 指令來調(diào)用 DLL 函數(shù)從 Java。
?
要使用 J/Direct, 您需要安裝 1.02.4337 版本或更高的 Microsoft 編譯器 for Java (Jvc.exe) 和 Microsoft 虛擬機(jī) for Java 2252 或更高版本。 編譯器就用 Microsoft SDK for Java 2.0 x 或更高版本。 虛擬機(jī), 但是, SDK for Java 附帶 3.2 和以后, 版本中已不再并且必須下載 seperately。 有關(guān)詳細(xì)信息, 請?jiān)L問以下 Microsoft 網(wǎng)站:?
http://www.microsoft.com/mscorp/java/
?站點(diǎn)。?
當(dāng)執(zhí)行 Java 應(yīng)用程序, 如果遇到一個(gè) UnsatisifiedLinkError, 然后檢查您的編譯器版本。 如果編譯器不支持 J/Direct, MicrosoftWin 虛擬機(jī)將試圖鏈接本機(jī)方法使用原始本機(jī)接口, 因此不會成功。
參考
?支持有關(guān) VisualJ++ 和 SDKforJava, 請?jiān)L問以下 MicrosoftWeb 站點(diǎn)獲取:?
http://www.microsoft.com/java
Warning: This article has been translated automatically
========
Java中調(diào)用Windows API的方法
要在Java中調(diào)用Windows API,最簡單的方法就是使用JNative.jar中提供的接口。該庫已經(jīng)對Linux和Windows系統(tǒng)中的API進(jìn)行了封裝,例如對Windows,使用它里面的接口調(diào)用就和在Delphi等開發(fā)工具中的調(diào)用方法是一樣的,因?yàn)楹瘮?shù)的名字和參數(shù)都是一樣的。下面說明其用法。
?
安裝方法:將JNative.jar加到classpath中即可。
?
假如現(xiàn)在要給QQ的窗口發(fā)送消息,程序如下:
?
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調(diào)用C/C++ API 講解及代碼示例?
JAVA
我們知道Java是一種平臺無關(guān)性的語言,平臺對于上層的java代碼來說是透明的,所以在多數(shù)時(shí)間我們是不需要調(diào)用本地方法,但是假如你遇到了以下情況,你可能就需要使用Java調(diào)用本地方法了:
你的Java代碼需要得到一個(gè)文件的屬性。但是你找遍了JDK幫助文檔也找不到相關(guān)的API。
在本地還有一個(gè)別的系統(tǒng),不過它不是Java語言實(shí)現(xiàn)的,這個(gè)時(shí)候你需要把兩套系統(tǒng)整合到一起。
你的Java代碼中需要用到某種算法,不過算法是用C實(shí)現(xiàn)并封裝在動態(tài)鏈接庫文件(DLL)當(dāng)中的。
?
對于上述的三種情況,如果沒有JNI的話,那就會變得異常棘手了。JNI其實(shí)是Java Native Interface的簡稱,也就是java本地接口。它提供了若干的API實(shí)現(xiàn)了和Java和其他語言的通信(主要是C&C++)。
?
在Java中有一些native方法,這些方法只有方法簽名但是沒有方法體。其實(shí)這些naive方法就是我們說的 java native interface。它提供了一個(gè)調(diào)用(invoke)的接口,然后用C或者C++去實(shí)現(xiàn)。
?
JNI概述
?
JVM封裝了各種操作系統(tǒng)實(shí)際的差異性的同時(shí),提供了JNI技術(shù),它是一種雙向的接口,使得開發(fā)者可以通過Java代碼調(diào)用到各種native的庫,反之亦然。所以JNI(Java Native Interface)能作為Java語言的一部分,她能夠作為粘合劑將Java應(yīng)用和其他本地應(yīng)用(C/C++,Delphi)集合在一起。
?
作為一個(gè)雙向的接口,JNI能支持兩種native代碼:native libraries 和native applications。
你能使用JNI去寫一些native methods去允許Java Applications能呼叫native libraries中的函數(shù),native methods的具體實(shí)現(xiàn)是可能C,C++或者Delphi。
JNI也支持嵌入一個(gè)JVM實(shí)現(xiàn)到一個(gè)本地應(yīng)用程序中去,去執(zhí)行那些用Java語言編寫的的模塊.比如,一個(gè)C++編寫的瀏覽器利用內(nèi)嵌的JVM去執(zhí)行下載到本地的applet。
?
實(shí)現(xiàn)步驟:
?
1) 完成Java代碼,編寫好Java調(diào)用類。
?
2) 編譯你的Java類。
?
3) 用javah生成編譯好的class文件對應(yīng)的C/C++ 函數(shù)的頭文件。
?
4) 實(shí)現(xiàn)頭文件中的函數(shù)原型,編寫native代碼。
?
5) 將native代碼編譯打包成DLL庫(win32)或共享庫(Linux)。
?
6) 將你的Java代碼跑起來
?
?
例子
?
1. 編寫Java代碼。
?
注意:
?
(1) 調(diào)用本地代碼的java方法,要設(shè)置成native的。
?
(2) 要使用System的LoadLibrary方法去加載包含本地方法實(shí)現(xiàn)的庫。
?
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,內(nèi)容如下:
?
Cpp代碼:
/* DO NOT EDIT THIS FILE - it is machine generated */ ?
#include <jni.h> ?
/* 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 ?
??
注意,在執(zhí)行javah的時(shí)候,要輸入完整的包名和類名。否則在以后的測試調(diào)用過程中會發(fā)生java.lang.UnsatisfiedLinkError這個(gè)異常。
?
4. 實(shí)現(xiàn)C++代碼。在VS2008中創(chuàng)建一個(gè)Win32 project,類型為DLL。
?
將剛才生成的頭文件eric_test_JNITest.h拷到工程目錄下,并且在項(xiàng)目中導(dǎo)入到Header Files里面。打開StdAfx.h文件,在最后面添加:
#include "jni.h" ?
#include "eric_test_JNITest.h" ?
打開JNITest.cpp文件,在其中添加實(shí)現(xiàn)代碼。函數(shù)名為頭文件中定義的函數(shù)聲明。
#include <iostream> ?
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方法,用來得到j(luò)ava string的字符串。
?
5. 構(gòu)建C++項(xiàng)目。會出現(xiàn)"Cannot open include file: 'jni.h': No such file or directory"的錯(cuò)誤,解決方法是將以下文件拷貝到C++工程目錄下
%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\win32\jni_md.h
?
同時(shí)將頭文件eric_test_JNITest.h中的 #include <jni.h> 改為
?
01.#include "jni.h" ?
?
然后重新build,將在debug目錄下生成JNITest.dll文件。
?
6. 將dll文件復(fù)制到Java工程的bin目錄下(這個(gè)位置十分重要,否則會出現(xiàn)not found的異常),并運(yùn)行程序
?
java eric.test.JNITest ?
?
將輸出結(jié)果"Hello, world called by Java Native Interface"。
========
jni java調(diào)用win32 dll的方法?
1 在java中寫好java需要的win32 dll中需要的函數(shù)說明 ,并編譯成功
?
?2 ?在win32 的cmd中,到j(luò)ava文件所在的目錄(eg: d:\java\isoline\com\util)下,調(diào)用命令:
?
? ? ?1)javac objectiveAnalyse.java ? 此時(shí)成功后,會在目錄d:\java\isoline\com\util下生成objectiveAnalyse.class文件
? ? ?(2) cmd轉(zhuǎn)當(dāng)前目錄到d:\java\isoline ? javah -jni com.util.objectiveAnalyse ?,即可生成c++ dll所需要的com_util_objectiveAnalyse.h文件
?
3 ?此時(shí) 會在當(dāng)前目錄下生成java需要的com_util_objectiveAnalyse.h文件,文件中產(chǎn)生了函數(shù)Java_PictureFactoryPlugin_GetDataPicture()
?
4 ? 手工改成java需要的包結(jié)構(gòu),如java需要 com_util 包結(jié)構(gòu),則改為:Java_com_util_PictureFactoryPlugin_GetDataPicture()
?
5 ?在cpp文件中實(shí)現(xiàn):Java_com_util_PictureFactoryPlugin_GetDataPicture() 的功能即可。
?
6 生成win32 dll ,就可以被java調(diào)用 了
?
========
使用 J-Interop 在 Java 中調(diào)用WMI
有關(guān)WMI的小知識
Windows管理規(guī)范(WMI)是微軟對來自分布式管理任務(wù)組(DMTF)的基于Web的企業(yè)管理(WBEM)和通用信息模型(CIM)標(biāo)準(zhǔn)的實(shí)現(xiàn)。WMI用于訪問Windows系統(tǒng)、應(yīng)用、網(wǎng)絡(luò)、設(shè)備等組件,并管理它們。連接到一臺機(jī)器通過DCOM進(jìn)行管理。因此,有關(guān)DCOM的小知識將有助于本文的理解。你可以到MSDN了解有關(guān)WMI的更多細(xì)節(jié)。
J-Interop
市場上有一些在使用 JAVA 調(diào)用 WMI 的好庫,包括 J-Interop、JACOB-Project 和 J-Integra。其中,我更喜歡J-Interop,因?yàn)樗峭耆赓M(fèi)和開源的API。它提供了沒有任何依賴的純DCOM橋,完全用Java編寫的沒有任何JNI代碼。
使用WMI管理Windows服務(wù)
現(xiàn)在,來看一個(gè)使用JAVA調(diào)用WMI的例子。這個(gè)例子利用J-Interop的API使用Win32_Service類解釋W(xué)MI操作,將啟動和停止在這個(gè)例子中的窗口服務(wù)。
步驟1:連接到WBEM服務(wù)
下面的代碼示例顯示了使用J-Interop如何初始化DCOM會話,并連接到遠(yuǎn)程DCOM服務(wù)使。它使用SWbemLocator對象連接到SWbemServices,SWbemServices對象提供對本地或遠(yuǎn)程計(jì)算機(jī)WMI的訪問,它調(diào)用“ConnectServer”方法連接到SWbemServices。在本例中,提供管理員級別的用戶連接到遠(yuǎn)程計(jì)算機(jī)。
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=遠(yuǎn)程計(jì)算機(jī)域名,hostIP=遠(yuǎn)程計(jì)算機(jī)IP地址,用戶名=管理員級別的用戶,密碼=密碼)
第2步:獲取Win32_Service實(shí)例
一旦你獲得對SWbemServices對象的引用,就可以調(diào)用這個(gè)類的任何方法。其中WbemServices.InstancesOf方法獲得任何Win32類的實(shí)例。
也可以使用WMI查詢語言(WQL)達(dá)到同樣的目的,如下所示:
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());
第三步:執(zhí)行方法
現(xiàn)在,已得到Win32_Service類的實(shí)例,可采用下述代碼來調(diào)用同一類的方法,因?yàn)?#xff0c;它返回多個(gè)服務(wù)實(shí)例,要列舉它們以便獲取IJIDispatcher服務(wù)。
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());
}
現(xiàn)在,下面的代碼顯示了一個(gè)使用WMI啟動和停止Windows服務(wù)的完整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 調(diào)用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調(diào)用.dll文件
一.在程序用jnative調(diào)用window的dll
1. ? 安裝
http://sourceforge.net/projects/jnative
解壓后得到3個(gè)文件:JNativeCpp.dll,libJNativeCpp.so,JNative.jar,其中:
JNativeCpp.dll ? ? 放在windows/system32目錄下
libJNativeCpp.so ? ?linux下使用
JNative.jar ? ? ? ? ?導(dǎo)入工程中
2. ? 使用
2.1. ? ? 加載dll文件
JNative可使用兩種方式加載dll文件:
a.使用System.loadLibrary加載,使用此方法可加載系統(tǒng)目錄中的dll文件。
b.可以先把dll文件復(fù)制到system32目錄下,使用文件前綴名作為參數(shù)來加載dll文件。使用System.load加載,此方法參數(shù)為dll文件全路徑名。
2.2. ? ? 調(diào)用函數(shù)
a、首先創(chuàng)建JNative對象:
JNative jnative = new JNative(dll文件名, 函數(shù)名);
b、設(shè)置返回值類型:
jnative.setRetVal(Type.INT);
c、設(shè)置參數(shù)
jnative.setParameter(0, Type.STRING, …); //設(shè)置第一個(gè)參數(shù)為字符串
jnative.setParameter(1, Type.INT, String.valueof(…)); ? ? ? //設(shè)置第二個(gè)參數(shù)為整數(shù)
d、執(zhí)行
n.invoke();
e、獲取返回值
Integer.parseInt(jnative.getRetVal());
3.實(shí)例
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的一些特性,如枚舉、靜態(tài)引入等,所以在JDK1.4下是不能用的。
二.在程序用jawin調(diào)用window的dll
jawin 可以對dll中的方法進(jìn)行調(diào)用,也可以調(diào)用com中的方法.內(nèi)部還提供了一個(gè)工具,直接對 com組件導(dǎo)出成 java的類,個(gè)人認(rèn)為很方便。
下面是我們作的一個(gè)測試,很順利便通過了。
1、下載jawin:http://jawinproject.sourceforge.net/。
2、配置:
? ? a.將jawin.jar放于%JAVA_HOME%/jre/lib/ext下 。
? ? b.將jawin.dll放于c:/winnt/system32下。否則將出現(xiàn)錯(cuò)誤:COMException : no jawin in java.library.path;
? ? 也可將jawin.dll放于每個(gè)項(xiàng)目目錄下。
?
? ?c.至此在Editplus中調(diào)試Jawin/NJawin的例子,可以通過。 而在Eclipse中有時(shí)還會出上面的錯(cuò)誤:COMException : no jawin in java.library.path。
? ?d.在Eclipse中,菜單->window->preference->Java->installed JREs 將原來的remove,重新建一個(gè)指到你的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調(diào)用com組件, 如word:
//創(chuàng)建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");// ? ? ? ? ? ? ? 創(chuàng)建word對象
? ? ? ? ? ? ? ? ? ? ?app.put("Visible",true); // ? ? ? ? ? ? ? ? ? ? 使word可見
? ? ? ? ? ? ? ? ? ? ?DispatchPtr docs=(DispatchPtr)app.get("Documents"); // ? ? ? ? ? ? ? ? 獲得document對象集合
? ? ? ? ? ? ? ? ? ? ?DispatchPtr doc=(DispatchPtr)docs.invoke("Add"); ?// ? ? ? ? ? ? ? ? ? ?新增一個(gè)文檔
? ? ? ? ? ? ? ? ? ? ?app.invoke("Activate"); // ? ? ? ? ? ? ? ? ? ?激活當(dāng)前文檔
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ?DispatchPtr objTextFont=(DispatchPtr)((DispatchPtr)doc.get("Content")).get("Font");
// ? ? ? ? ? ? ? ? ? 取得Font對象
? ? ? ? ? ? ? ? ? ? ?objTextFont.put("Name","黑體");
// ? ? ? ? ? ? ? ? ? 設(shè)置字體
? ? ? ? ? ? ? ? ? ? ?objTextFont.put("Size","48");
// ? ? ? ? ? ? ? ? ? 設(shè)置字號
? ? ? ? ? ? ? ? ? ? ?DispatchPtr docSelection=(DispatchPtr)app.get("Selection");
// ? ? ? ? ? ? ? ? ? 取得Selection對象
? ? ? ? ? ? ? ? ? ? ?docSelection.invoke("TypeText","Jawwintesttext!/nJawin測試文本。");
// ? ? ? ? ? ? ? ? ? 使用TypeText方法添加文本
? ? ? ? ? ? ? ? ? ? ?doc.invoke("SaveAs","d://jawintest.doc");
// ? ? ? ? ? ? ? ? ? 保存文檔(保存在C盤根目錄下)
? ? ? ? ? ? ? ? ? ? ?doc.invoke("Close");
// ? ? ? ? ? ? ? ? ? 關(guān)閉當(dāng)前文檔,去掉前面的注釋符并重新編譯后可生效
? ? ? ? ? ? ? ? ? ? ?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();
? ? ? ? ? ? ? }
? ? ? ?}
}
?
//調(diào)用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");
? ? ? ? ? ? ? ? ? ? ?// 創(chuàng)建word對象
? ? ? ? ? ? ? ? ? ? ?app.put("Visible", false);
? ? ? ? ? ? ? ? ? ? ?// 設(shè)置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");
? ? ? ? ? ? ? ? ? ? ?// 關(guān)閉word
? ? ? ? ? ? ? ? ? ? ?Ole32.CoUninitialize();
? ? ? ? ? ? ? ? ? ? ?// 釋放對象
? ? ? ? ? ? ? ? ? ? ?System.out.println("/n轉(zhuǎn)換完成!");
? ? ? ? ? ? ? ? ? ? ?System.out.println("/n文件名:" + fileMainName + ".html");
? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? ?System.out.println("/n該文件不存在!或者其他錯(cuò)誤(如:運(yùn)行環(huán)境問題)!");
? ? ? ? ? ? ? }
? ? ? ?}
}
?
========
12 其他鏈接
http://www.cnblogs.com/cy163/category/223619.html
最近在做實(shí)驗(yàn)希望實(shí)現(xiàn)基于JNI技術(shù)在Java中使用 Slex.dll
Calling C Library Routines from Java
使用 SWIG 實(shí)現(xiàn) Java 調(diào)用 C++ DLL
一種實(shí)現(xiàn) Java調(diào)用C++的DLL的方法
總結(jié)
以上是生活随笔為你收集整理的java 调用win32 api 学习总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java Servlet 开发常用代码、
- 下一篇: .net 插件式开发学习总结