【问题标题】:Runtime.getRuntime().exec() not opening correct windows file explorerRuntime.getRuntime().exec() 没有打开正确的 Windows 文件资源管理器
【发布时间】:2016-03-22 17:46:57
【问题描述】:

我正在使用 Java 的 Runtime.getRuntime().exec(String command) 打开指定文件的 Windows 文件资源管理器。为此,我正在使用命令:

explorer pathToOpen

这几乎一直有效,除非路径包含一些在 NFD(规范化形式规范分解)规范化形式中的 unicode 字符。

让我在这里举个例子。我有以下命令:

资源管理器 C:\Test\földer

我的本​​地文件系统中有所有“C 盘”、“Test”和“földer”文件夹。 'földer' 包含 NFD 形式的 unicode 字符 'ö'。此外,我确保我传递给 exec 方法的字符串也包含与这些文件夹中相同的 unicode 字符,即 NFD 形式。

但这会在我的用户文件夹中打开“文档”文件夹,而不是打开“文件夹”。如果我创建另一个文件夹,让我们说“földerInNFC”,其中“ö”是 NFC 形式,那么如果我执行“explorer C:\Test\földerInNFC”,那么它会打开所需的文件夹,即“földerInNFC”。

我也可以从 Windows 命令提示符中看到相同的结果。我一一复制并粘贴了两条路径,并且可以看到相同的行为。 Here is a snippet of my command prompt。我还可以看到命令提示符无法识别 NFD 形式的“ö”,但它能够识别 NFC 形式的“ö”。

Runtime.getRuntime().exec() 和 cmd 是否都不支持 NFD unicode 字符?如果不是,那么在 java 中是否有另一种方法可以为包含 NFD 形式的 unicode 字符的特定文件或文件夹打开 Windows 文件资源管理器?

【问题讨论】:

  • 这种方式不会将参数传递给可执行文件,请改用 ProcessBuilder
  • 我也用过。它提供与上述相同的输出。

标签: java windows unicode unicode-normalization


【解决方案1】:

您可以使用包含 NFD unicode 字符的路径名打开 Windows 资源管理器,如下所示

假设在C:\temp 一个文件夹földer 中(如果在“FOLDER~1”之后的下面看起来乱码,可能与您的浏览器使用的字体有关)

16/12/2015  15:39    <DIR>          FOLDER~1     földer

sn-p 打开C:\temp\földer(包含NFD unicode 字符)

String nfdPath = "fo\u0308lder"; // földer in NFD unicode
File file = new File("c:/temp/" + nfdPath);
// uncomment the next line if you want that folder to be created first
// file.mkdir();
java.awt.Desktop.getDesktop().open(file);

编辑要打开文件夹并选择一个文件,您可以使用该文件夹的短名称。您可以使用JNA 检索该文件夹的短名称。在下面找到第二个问题的简短 sn-p。 ;-)

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import java.io.File;
import java.io.IOException;

public class OpenFolderAndSelectItem {

    public static String getShortPathName(String path) {
        char[] result = new char[256];
        Kernel32.INSTANCE.GetShortPathName(path, result, result.length);
        return Native.toString(result);
    }

    // add exception handling, left out only for the example
    public static void main(String[] args) throws IOException {
        String nfdFolderName = "c:\\temp\\fo\u0308lder";
        System.out.println("foldername with unicode character in NFD form: "
            + nfdFolderName);
        File file = new File(nfdFolderName);
        file.mkdir();
        // create some dummy files in that folder
        for (char c = '0'; c <= '9'; c++) {
            new File(nfdFolderName + "/file" + c).createNewFile();
        }
        // get the 8.3 short name of the folder
        String nfdFolderShortName = getShortPathName(nfdFolderName);
        // open the folder c:\temp\földer and select the file 'file4'
        ProcessBuilder process = new ProcessBuilder();
        process.command("explorer", "/select," + nfdFolderShortName
            + "\\file4");
        process.inheritIO();
        process.start();
    }
}

对于下一个可能的问题“我如何选择多个文件”:我相信唯一的方法是编写自己的库/工具来实现SHOpenFolderAndSelectItems

【讨论】:

  • 谢谢它的工作!但是如果我也想选择那个文件/文件夹,那么呢?我的意思是相当于“explorer /select,C:\Test\földer”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 2012-05-05
相关资源
最近更新 更多