【问题标题】:How do I launch another app from Java on a Mac如何在 Mac 上从 Java 启动另一个应用程序
【发布时间】:2013-10-18 18:17:36
【问题描述】:

我编写的在 Windows 上运行良好的代码在 Mac 上运行不正常。 我打电话的简短形式:

Runtime.getRuntime().exec (String ["/Applications/CM Battle for Normandy/CM Battle for Normandy.app" "2vs2 White Manor 072.ema"], null, "/Applications/CM Battle for Normandy/");

我尝试运行的软件没有设置与 .ema 文件的文件关联(如果您好奇,这是一个游戏)

我的代码如下所示:

    private void launchGameProgram (PBEMGame selectedGame) {
    if (selectedGame == null)
        return; // no work to do

    InstalledProgram program = selectedGame.playedWith ();
    if (program == null)
        return; // no work to do

    try {
        Vector<String> command = new Vector<String> ();
        command.add (program.getExeFile ().getAbsolutePath ());
        if (selectedGame.getLastTurn () != null  &&  selectedGame.getLastTurn ().getTurnFile () != null)  {
            //  Add the turn file name to the command
            command.add (selectedGame.getLastTurn ().getTurnFile ().getName ());
        }
        GUIApplicationPolicy.getLog ().log ("WTII testing: About to launch: " + command.toString () + " from: " + program.getExeFile ().getParentFile ());
        Runtime.getRuntime ().exec (command.toArray (new String[command.size ()]), null, program.getExeFile ().getParentFile ());
    } catch (IOException exception) {
        GUIApplicationPolicy.getLog ().log (exception);
        exception.printStackTrace();
    }
}

这会在日志中产生以下内容:

!Entry: 2013/10/02 23:08:33.017
!Message: WTII testing: About to launch: [/Applications/CM Battle for Normandy/CM Battle for Normandy.app, 2vs2 White Manor 072.ema] from: /Applications/CM Battle for Normandy

!Entry: 2013/10/02 23:08:33.023
!Exception: Cannot run program "/Applications/CM Battle for Normandy/CM Battle for Normandy.app" (in directory "/Applications/CM Battle for Normandy"): error=13, Permission denied
!Stack: java.io.IOException: Cannot run program "/Applications/CM Battle for Normandy/CM Battle for Normandy.app" (in directory "/Applications/CM Battle for Normandy"): error=13, Permission denied
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
    at java.lang.Runtime.exec(Runtime.java:617)
    at com.lesliesoftware.whoseturnisit.WhoseTurnIsIt.launchGameProgram(Unknown Source)
    at com.lesliesoftware.whoseturnisit.WhoseTurnIsIt.access$3100(Unknown Source)
    at com.lesliesoftware.whoseturnisit.WhoseTurnIsIt$LaunchSelectedGameProgram.widgetSelected(Unknown Source)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3776)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1367)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1390)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1375)
    at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1187)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3622)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3277)
    at com.lesliesoftware.whoseturnisit.WhoseTurnIsIt.main(Unknown Source)
Caused by: java.io.IOException: error=13, Permission denied
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:135)
    at java.lang.ProcessImpl.start(ProcessImpl.java:130)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1022)
    ... 14 more

任何帮助或指导将不胜感激。

【问题讨论】:

    标签: java macos swt exec


    【解决方案1】:

    试试这个..

    Runtime.getRuntime().exec (String ["open /Applications/CM Battle for Normandy/CM Battle for Normandy.app" "--args" "2vs2 White Manor 072.ema"], null, "/Applications/CM Battle for Normandy/")
    

    更新:在与伊恩讨论之后..

    Runtime.getRuntime().exec (String ["open" "/Applications/CM Battle for Normandy/CM Battle for Normandy.app" "--args" "2vs2 White Manor 072.ema"], null, "/Applications/CM Battle for Normandy/")
    

    【讨论】:

    • 有趣的是 open 在这种情况下做什么?
    • @IanLeslie - open 是用于执行应用程序的 Mac 命令。从Terminal 尝试open /Applications/CM Battle for Normandy/CM Battle for Normandy.app --args 2vs2 White Manor 072.ema 进行确认。
    • 另外,我已经编辑了答案,在其中添加了--args,这是向应用程序传递参数所必需的。
    • 我终于回到了这个......这产生了消息:无法运行程序“打开 /Applications/CM Battle for Normandy/CM Battle for Normandy.app”(在目录“/Applications/CM诺曼底战役"): error=2, 没有这样的文件或目录
    • 尝试在名称后面添加斜杠。我不知道为什么,但这对我有用。
    【解决方案2】:

    这是从命令行运行的东西吗?我看到了一个命令变量,但我没有看到任何关于它实际上是/做什么的上下文。您可能需要为任何命令添加“sudo”前缀(假设它在终端中)。我只是从权限错误中推断出来的。

    另外,我看到一个“getExeFile”。也许我误解了这一点,但你为什么要在 MacOS 上寻找 .exe?同样,我可能只是误解了这段代码。无论如何,我希望这能帮助或至少帮助你动动脑筋。

    【讨论】:

    • 不确定如何回答“这是从命令行运行的”。我没有命令行,但我正在尝试启动另一个应用程序,在 Windows 上,这些参数与命令行窗口中使用的参数相同。
    • getExeFile 是我为自己的私有类编写的一种方法,该方法最初是在 Windows 上编写的。我从来没有想过在 Mac 上可执行的东西(因为没有更好的词)将是一个目录而不是一个文件。所以名称只是一个工件,实际返回的 File 对象在 windows 上是 xxx.exe,在 mac 上是 xxx.app。
    • @IanLeslie“那个可执行的东西”是一个二进制文件,正如我在我的回答中发布的那样,Mac 上的应用程序有二进制文件
    • 了解@MateuszDymczyk,我正在跟进您的建议(以及来自@vidit 的公开建议)。我的意思是从最终用户的角度来看,Mac 将 .app 文件夹呈现为可选的可执行实体。这与可执行实体是文件的任何其他操作系统都有很大不同。
    【解决方案3】:

    您正在尝试执行“CM Battle for Normandy.app”,这是一个文件夹(是的,我知道 .app 扩展名可能会产生误导)。您要做的是在该文件夹中找到一个二进制文件并执行它。通常在该文件夹中有一个 Contents 文件夹,其中有一个 MacOS 文件夹,并且在该文件夹中应该有一个可执行文件(可能是“CM Battle for Normandy”)。

    您可以使用终端或 Finder 找到它。

    所以我的任务是改变:

    "/Applications/CM Battle for Normandy/CM Battle for Normandy.app"
    

    "/Applications/CM Battle for Normandy/CM Battle for Normandy.app/Contents/MacOS/CM Battle for Normandy"
    

    但可能会略有不同。它没有像 Windows 上那样的扩展名(即 .exe 或 smth),但那是因为 MacOS 是 Unix 类型系统。

    【讨论】:

    • 好的,取得了一些进展。但是该应用程序没有正常启动 - 它尝试但失败了 - 我认为它未能找到它所依赖的一些库。我不确定,因为我没有从这个日志中得到日志。在 Windows 上,如果我尝试使用不正确的“在目录中启动”启动游戏,我会看到类似的结果。我将尝试告诉它从 .app 目录开始,看看会得到什么。正如您可能知道的那样,我没有 Mac,所以我是通过一个乐于助人的用户来做这件事的。但进展非常缓慢。
    • 我认为你做不到。您需要使用 osx“打开”命令 - 它知道如何正确查看 .app/ 文件夹。我不认为 osx 期望任何人在里面闲逛并找到要运行的二进制文件......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多