封装和产生另一个应用程序并注入参数

时间:2018-10-07 22:28:52

标签: objective-c macos cocoa nswindow launch-services

我的问题是我有一个孩子.app,我想在注入一些参数后运行它。要做的是将应用程序作为父应用程序运行(启动它以同步并将焦点/激活事件传播到子应用程序)。

我的目标是创建一个可启动另一个应用程序的“父应用程序”,例如OtherApp.app。它应该看起来像“父应用程序” OtherApp.app(即,不是作为单独的应用程序显示在扩展坞中,而是OtherApp.app的窗口应包含在“父应用程序”中')。我想这样做的原因是,我可以将一些初始化变量传递给OtherApp.app,而无需修改.app本身。


我采取的方法

  1. 第一种方法是最简单的。只需使用system(@"VAR=VALUE /Applications/OtherApp.app")。但是,与此有关的问题是,“父应用程序”将立即退出,而OtherApp.app将作为单独的应用程序在Dock中打开。

  2. 第二种方法:我试图做的是将NSWorkspaceNSRunningApplication一起使用,但是这不是同步的,问题在于“父应用程序”将再次立即消失:

    #import <Cocoa/Cocoa.h>
    
    int main(int argc, const char * argv[]) {
        NSRunningApplication* childApp = [[NSWorkspace sharedWorkspace]
                                          openURL:[NSURL fileURLWithPath:@"/Applications/OtherApp.app"]
                                          options:NSWorkspaceLaunchDefault|NSWorkspaceLaunchWithoutAddingToRecents
                                          configuration:@{
                                              NSWorkspaceLaunchConfigurationEnvironment: @{
                                                      @"VAR": @"VALUE"
                                              }
                                          } error:NULL];
    }
    
  3. 第三种方法是使用启动服务。但是,这就是我的问题所在-我找不到让我传递环境变量或“启动服务键”(例如LSUIElement)的未弃用的API,也找不到让我传递环境变量的方法。这也会立即退出(我不熟悉Launch Services的内部,也许有人可以启发我?)

    #import <Cocoa/Cocoa.h>
    
    int main(int argc, const char * argv[]) {
        LSLaunchURLSpec launchSpec;
        launchSpec.appURL = CFBridgingRetain([NSURL fileURLWithPath:@"/Applications/OtherApp.app"]);
        launchSpec.asyncRefCon = NULL;
        launchSpec.launchFlags = kLSLaunchDefaults;
        launchSpec.passThruParams = NULL;
        // Where can I specify environment vars or args?
        return LSOpenFromURLSpec(&launchSpec, NULL);
    }
    

可能的解决方案

  1. 创建一个与NSApplication进行通信的OtherApp.app,以便“父应用”不会立即退出。问题再次出在这里,它们现在是扩展坞中的两个应用程序,并且还需要保持同步,这似乎是一项更加复杂的任务。
  2. 弄清楚如何将环境变量传递给LS(启动服务)API,以及如何控制产生的应用程序的焦点。
  3. 尽管我通常不能将NSApplicationMain与可执行文件一起使用,但可以以某种方式访问​​包并动态加载OtherApp.app的{​​{1}}(这样会引发错误)。

尽管对替代解决方案的任何帮助将不胜感激,但现在#2感觉是最好的选择。

0 个答案:

没有答案