我正在寻找一种方法来查找在操作系统尝试打开给定文件时将启动的程序名称(在我的代码中)。我不会启动应用程序我只是在寻找它的名字。理想情况下,我正在寻找/构建的例程将采用文件名并返回一个字符串。我在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的。
答案 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的更好解决方案,我还是不得不使用它。