Моя проблема в том, что у меня есть ребенок .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];
}
Третий подход используетСервисы запуска.Однако это то, о чем спрашивает мой вопрос: я не могу найти ни одного устаревшего API, который бы позволял мне передавать переменные среды или «ключи сервисов запуска» (например, LSUIElement), и не мог найти способ, который позволял бы мне передавать переменные среды.Это также мгновенно выходит (я не знаком с внутренностями 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
, хотя я обычно не могу использовать NSBundle
сисполняемый файл (он выдает ошибку, говорящую об этом).
Сейчас # 2 кажется лучшим выбором, хотя любая помощь в альтернативных решениях будет принята с благодарностью.