Инкапсуляция и порождение другого приложения и внедрение параметров - PullRequest
0 голосов
/ 08 октября 2018

Моя проблема в том, что у меня есть ребенок .app, который я хотел бы запустить после введения некоторых параметров.Что нужно сделать, так это запустить приложение как родительское приложение (запустить его синхронизацию и передать события фокуса / активации в дочернее приложение).

Цель для меня - создать «родительское приложение», которое запускает другое приложение.например OtherApp.app.Это должно выглядеть так, как будто «родительское приложение» равно OtherApp.app (то есть не отображается как отдельное приложение в доке, но окна OtherApp.app должны содержаться «родительским приложением»).Причина, по которой я хочу это сделать, заключается в том, что я могу передать некоторые переменные инициализации OtherApp.app без изменения самого .app.


Подходы, которые я предпринял

  1. Первый подход самый простой.Просто используя system(@"VAR=VALUE /Applications/OtherApp.app").Однако проблема в этом заключается в том, что «родительское приложение» мгновенно завершает работу и OtherApp.app открывается как отдельное приложение в Dock.

  2. Второй подход: я пытался сделатьэто использование 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];
    }
    
  3. Третий подход используетСервисы запуска.Однако это то, о чем спрашивает мой вопрос: я не могу найти ни одного устаревшего 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);
    }
    

Возможные решения

  1. Создайте NSApplication, который связывается с OtherApp.app, чтобы «родительское приложение» не закрывалось немедленно.Проблемы заключаются в том, что, опять-таки, теперь они являются двумя приложениями в доке, и сохранение синхронизации в синхронизации кажется более сложной задачей.
  2. Выясните, как передавать переменные среды в LS (ЗапуститьСервисы) API, а также возможность управлять фокусом порожденного приложения.
  3. Каким-то образом получить доступ к пакету и динамически загрузить NSApplicationMain из OtherApp.app, хотя я обычно не могу использовать NSBundle сисполняемый файл (он выдает ошибку, говорящую об этом).

Сейчас # 2 кажется лучшим выбором, хотя любая помощь в альтернативных решениях будет принята с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...