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

时间:2015-12-11 21:48:32

标签: java swing swt cross-platform

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

我能找到的最简单的解决方案是使用SWT的课程' Program'。虽然这假设我可以正确识别文件类型,这是另一个很大的蠕虫,我不会进入这里。

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

但由于种种原因,我不想尽可能使用SWT库。我使用Swing并且我真的不希望我的客户需要根据他们的操作系统下载不同的应用程序(jar)。我很清楚底层代码是依赖于操作系统/ Window Manager的。

  1. 任何人都知道SWT之外还有其他任何其他套餐吗?我找不到一个。或者类似的我可以剥离结果以获得我想要的东西?即使它仅适用于一个平台?我正在尝试使用Apache Tika,但我在那里看不到任何有用的东西。
  2. 任何关于在哪里开始写这个的提示?我知道这需要在Windows上阅读注册表。我需要这些代码才能在最新版本的Windows和OS X上运行。最终Linux而Linux窗口系统不是优先考虑的问题。
  3. 有没有办法在Eclipse中链接/加载SWT以使交叉依赖的部分使用SWT这个代码更轻巧,对最终用户来说是不可见的?我不是新编码,而是使用Eclipse。

1 个答案:

答案 0 :(得分:2)

以下是我的解决方案的简要说明。我做了相当多的狩猎,我决定只使用JNA库。 https://github.com/java-native-access/jna并在Macintosh上编写我自己的本机库以使其正常工作。

Windows:相当直接使用JNA。我叫FindExecutable&来自JNA的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:我尝试了各种各样的东西,最后决定编写我自己的小本地库来调用目标C

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

这个库很小(但如果我需要其他本机调用,我可以添加它)但是我需要编写一个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的更好解决方案,我还是不得不使用它。