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

标签 java windows winapi java-native-interface jna

在搜索如何执行此操作时,我发现了一些关于不同选项的模糊讨论,例如 JNI 与 JNA,但没有太多具体示例。

上下文:如果 Java 的 File.renameTo() 不能完成它的工作(无论出于何种原因;it is a little problematic),我想退回到直接使用这个 native Windows 函数,它是在 kernel32.dll ( from this answer ) 中定义:

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

那么,无论使用何种方法,您将如何从 Java 代码中调用该函数?我正在寻找最简单的方法,使用最少的非 Java 代码或额外的步骤(例如在编译或部署中)。

最佳答案

如果您使用 JNA,请考虑调用 MoveFileW直接 - 它省去了提供配置信息以在 Unicode 和 ANSI 调用之间进行选择的麻烦。

import java.io.*;
import com.sun.jna.*;

public class Ren {

  static interface Kernel32 extends Library {
    public static Kernel32 INSTANCE = (Kernel32) Native
        .loadLibrary("Kernel32", Kernel32.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 = Kernel32.INSTANCE.GetLastError();
    char[] lpBuffer = new char[1024];
    int lenW = Kernel32.INSTANCE.FormatMessageW(
        Kernel32.FORMAT_MESSAGE_FROM_SYSTEM
            | Kernel32.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 (!Kernel32.INSTANCE.MoveFileW(new WString(from),
        new WString(to))) {
      throw new IOException(getLastError());
    }
  }
}

编辑:我在检查代码后编辑了我的答案 - 我在签名中使用 char[] 是错误的 - 最好使用 WString .

关于java - 从 Java 调用 Windows 内核函数的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1000723/

相关文章:

c - 如何以编程方式确定 Windows 是否正在关闭?

c - 你实际上是如何使用 C 库的?

java - 为基于 testng 的框架进行测试用例清理的最佳方法

java - Amazon Java S3 SDK - 上传目录

java - JPQL 在 Select 语句中创建新对象 - 避免还是接受?

c++ - 在 C/C++ 窗口中终止进程

windows - 从 Windows 调用 ssh 时转义字符

delphi - 如何将相对 PIDL 转换为绝对 PIDL?

用于确定计算机是否使用电池供电的 C# 技术?

java - 如何创建一个实现 mouseListener 的类