从Java调用Windows内核函数最简单的方法是什么?

在寻找如何做到这一点的时候,我发现了一些关于不同选项的模糊讨论,比如JNI和JNA,但是没有太多具体的例子。

上下文:如果Java的File.renameTo()不能完成它的工作(无论什么原因; 有点问题 ),我想退回到直接使用这个在kernel32.dll中定义的本地Windows函数( 从此答案 ):

 BOOL WINAPI MoveFile( __in LPCTSTR lpExistingFileName, __in LPCTSTR lpNewFileName ); 

所以,使用任何方法,你将如何从Java代码中调用该函数? 我正在寻找最简单的方法,使用最less量的非Java代码或额外的步骤(例如编译或部署)。

Solutions Collecting From Web of "从Java调用Windows内核函数最简单的方法是什么?"

如果您使用JNA,请考虑直接调用MoveFileW – 这样可以节省必须提供配置信息以在Unicode和ANSI调用之间进行选择的功能。

 import java.io.*; import com.sun.jna.*; public class Ren { static interface coreel32 extends Library { public static coreel32 INSTANCE = (coreel32) Native .loadLibrary("coreel32", coreel32.class); public static int FORMAT_MESSAGE_FROM_SYSTEM = 4096; public static int FORMAT_MESSAGE_IGNORE_INSERTS = 512; public boolean MoveFileW(WString lpExistingFileName, WString lpNewFileName); public int GetLastError(); public int FormatMessageW(int dwFlags, Pointer lpSource, int dwMessageId, int dwLanguageId, char[] lpBuffer, int nSize, Pointer Arguments); } public static String getLastError() { int dwMessageId = coreel32.INSTANCE.GetLastError(); char[] lpBuffer = new char[1024]; int lenW = coreel32.INSTANCE.FormatMessageW( coreel32.FORMAT_MESSAGE_FROM_SYSTEM | coreel32.FORMAT_MESSAGE_IGNORE_INSERTS, null, dwMessageId, 0, lpBuffer, lpBuffer.length, null); return new String(lpBuffer, 0, lenW); } public static void main(String[] args) throws IOException { String from = ".\\from.txt"; String to = ".\\to.txt"; new FileOutputStream(from).close(); if (!coreel32.INSTANCE.MoveFileW(new WString(from), new WString(to))) { throw new IOException(getLastError()); } } } 

编辑:我检查代码后编辑我的答案 – 我错误地使用char []签名 – 这是最好使用WString 。

如果这真的是必要的(renameTo不工作,你肯定MoveFile会),我会使用JNA 。 看起来大部分的工作已经在com.mucommander.file.util中完成了。 coreel32.java / coreel32API.java 。

基于NativeCall库,我做了以下POC应用程序 。

它使用kernel32.dll中MoveFileA函数

它作为一个完整的工作示例与run.bat和所有jar和dll的地方。

它将包含的test.txt移动到test2.txt


如果您不喜欢NativeCall库版本,我会根据/在Java Native Access(JNA)库上执行另一个POC应用程序 。 这一次MoveFileAMoveFileW被实现和演示。