我的问题是我有一个孩子.app
,我想在注入一些参数后运行它。要做的是将应用程序作为父应用程序运行(启动它以同步并将焦点/激活事件传播到子应用程序)。
我的目标是创建一个可启动另一个应用程序的“父应用程序”,例如OtherApp.app
。它应该看起来像“父应用程序” 是 OtherApp.app
(即,不是作为单独的应用程序显示在扩展坞中,而是OtherApp.app
的窗口应包含在“父应用程序”中')。我想这样做的原因是,我可以将一些初始化变量传递给OtherApp.app
,而无需修改.app
本身。
第一种方法是最简单的。只需使用system(@"VAR=VALUE /Applications/OtherApp.app")
。但是,与此有关的问题是,“父应用程序”将立即退出,而OtherApp.app
将作为单独的应用程序在Dock中打开。
第二种方法:我试图做的是将NSWorkspace
与NSRunningApplication
一起使用,但是这不是同步的,问题在于“父应用程序”将再次立即消失:
#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];
}
第三种方法是使用启动服务。但是,这就是我的问题所在-我找不到让我传递环境变量或“启动服务键”(例如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);
}
NSApplication
进行通信的OtherApp.app
,以便“父应用”不会立即退出。问题再次出在这里,它们现在是扩展坞中的两个应用程序,并且还需要保持同步,这似乎是一项更加复杂的任务。LS
(启动服务)API,以及如何控制产生的应用程序的焦点。NSApplicationMain
与可执行文件一起使用,但可以以某种方式访问包并动态加载OtherApp.app
的{{1}}(这样会引发错误)。尽管对替代解决方案的任何帮助将不胜感激,但现在#2感觉是最好的选择。