java - 如何找到将启动给定文件的程序的名称?

标签 java swing swt cross-platform

我正在寻找一种方法来查找当操作系统尝试打开给定文件时将启动的程序名称(在我的代码中)。我不会启动我只是在寻找它的名字的应用程序。理想情况下,我正在寻找/构建的例程将采用文件名并返回一个字符串。我在 Eclipse 上用 Java 8 编程,需要我的 jar 文件来保持跨平台。

我能找到的最简单的解决方案是使用 SWT 的“程序”类。虽然这是假设我可以正确识别文件类型,但这是我不打算在这里讨论的另一大问题。

String ext = extractFileType(filename);
Program p2 = Program.findProgram(ext);
if (p2 != null) programName = p2.toString(); 

但出于多种原因,我不想尽可能使用 SWT 库。我正在使用 Swing,而且我真的不希望我的客户需要根据他们的操作系统下载不同的应用程序 (jar)。我很清楚底层代码依赖于操作系统/窗口管理器。

  1. 有人知道除了 SWT 之外还有其他软件包已经这样做了吗?我找不到一个。或者足够相似我可以剥离结果以获得我想要的?即使它只适用于一个平台?我正在试验 Apache Tika,但我看不到任何有用的东西。
  2. 关于从哪里开始自己写这篇文章的任何提示?我知道这需要读取 Windows 上的注册表。我需要这段代码在最新版本的 Windows 和 OS X 上工作。最终是 Linux,但 Linux 窗口系统不是优先考虑的。
  3. 有没有一种方法可以在 Eclipse 中链接/加载 SWT,从而使使用 SWT 的交叉依赖部分对最终用户来说更轻量并且不可见?我不是编码新手,而是使用 Eclipse。

最佳答案

这是我的解决方案的简要说明。我四处搜寻了很多,然后决定只使用 JNA 库。 https://github.com/java-native-access/jna并在 Macintosh 上编写我自己的 native 库以使其运行。

Windows:相当直接地使用 JNA。我正在从 JNA 调用 FindExecutable 和 PathFindExtension。

public interface MyShell32 extends Shell32 {
    MyShell32 INSTANCE = (MyShell32) Native.loadLibrary("shell32",  MyShell32.class, W32APIOptions.DEFAULT_OPTIONS);

    WinDef.HINSTANCE FindExecutable(String  lpFile, String lpDirectory, char[] lpResult);
}

{
 ...
    char[] returnBuffer = new char[WinDef.MAX_PATH];
    shell.FindExecutable(filename, null, returnBuffer);
    app = Native.toString(returnBuffer);
   ...
}

PathFindExtention() 调用类似,但返回一个指针,因此更直接。

Macintosh:我尝试了各种方法,最后决定编写我自己的小型本地库来调用 objective-c

rtnValue = [[NSWorkspace sharedWorkspace] getInfoForFile:filenameNS
                                             application:&AStr
                                                    type:&TStr];

这个库很小(但如果我需要其他 native 调用,我可能会添加它)但我需要编写一个 C/C++ shell 以及 Objective C 才能让它工作。然后我将这个库称为 JNA。与直接编写 JNI 没什么不同,但我发现编码更容易。

public interface NSWWraper extends Library  {
    /** The instance **/
    NSWWraper INSTANCE = (NSWWraper) Native.loadLibrary("NSWWraper", NSWWraper.class);

    // CP_NSWWraper
    Pointer FindFileInfo(String filename);
    void FreeMem(Pointer memory);
}

老实说,我还没有测试过这个调用大量文件的方法,所以我不知道它会减慢我的代码速度。 JNA 调用应该是昂贵的。有人问我的解决方案的时机很有趣,因为我不得不把它搁置一旁,昨天才让它在 Windows 上运行。我打算将其纳入我今天项目的其余部分。

编辑添加。我没有使用 JINI,因为我发现它在 Macintosh 上不再得到很好的支持,而 JNA 是适用于 Windows 的更好解决方案,无论如何我都不得不使用它。

关于java - 如何找到将启动给定文件的程序的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34233091/

相关文章:

java - 仅当不为空或不为空时 Gson 序列化字段

java - Java BigDecimal 中的 Karatsuba 乘法实现

java - 如何在特定半径的android studio中接收地址列表?

Java Swing - 单用户应用程序到多用户应用程序

java - 如何为 java.util.List 的数组列表添加监听器

java - 在SWT浏览器中异步打开页面

java - Java中无需使用try即可抛出异常

java - launch4j 捆绑 JRE 错误 ."This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted"

swt - 无需滚动即可填充 Eclipse RCP 编辑器的可见区域

java - actionPerformed 函数中的 if/else 语句不起作用