LaunchAgents для приложения с графическим интерфейсом - PullRequest
0 голосов
/ 20 сентября 2010

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

Я добавил plist-файл в папку / Libray / LaunchAgents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>KeepAlive</key>
 <false/>
 <key> LaunchOnlyOnce</key>
 <true/>
 <key>OnDemand</key>
 <false/>
 <key>RunAtLoad</key>
 <true/>
 <key>Label</key>
 <string>com.mycompany.myapp</string>
 <key>ProgramArguments</key>
 <array>
  <string>/Applications/mayapp.app/Contents/MacOS/myapp</string>
 </array>
</dict>
</plist>

Все выглядит нормально, приложение загружается, однако, когда я закрываю приложение, оно запускается сервисом launchd.

Какой ключ я должен добавить / изменить в своем файле plist, чтобы предотвратить постоянный перезапуск моего приложения.

Ответы [ 3 ]

1 голос
/ 20 сентября 2010

Если вы хотите запускать обычное приложение при входе в систему, я бы порекомендовал использовать API списка общих файлов LaunchServices, а не launchd. Вместо того, чтобы устанавливать список запуска, вы можете просто использовать этот API, чтобы добавить свое приложение к элементам входа пользователя (те, которые вы видите на преф-панели «Учетные записи» в Системных настройках). Преимущества этого: а) для пользователя более очевидно, почему приложение запускается при входе в систему, б) пользователю легче удалить его, и в) если пользователь удаляет ваше приложение, launchd будет жаловаться на ошибки консоли. когда не удается запустить (теперь отсутствует) приложение.

Похоже, что нет никакой справочной документации по API, но соответствующие функции находятся в LSSharedFileList.h. Код для этого будет выглядеть примерно так:

#import <CoreServices/CoreServices.h>

...

LSSharedFileListRef loginItemList = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemList != NULL)
{
    LSSharedFileListRef myItem = LSSharedFileListInsertItemURL(loginItemList, kLSSharedFileListItemLast, NULL, NULL, (CFURLRef)[[NSBundle mainBundle] bundleURL], NULL, NULL);
    //We don't do anything with the new item, but we need to release it so it doesn't leak
    if (myItem != NULL)
        CFRelease(myItem);
    CFRelease(loginItemList);
}

Если вы хотите, чтобы этот элемент запускался для всех пользователей, а не только для текущего пользователя, вошедшего в систему, вы можете использовать kLSSharedFileListGlobalLoginItems вместо kLSSharedFileListSessionLoginItems.

0 голосов
/ 25 марта 2012

удалите ключ Keep Alive и запустите ключ только один раз ... так как вам требуется запускать приложение только один раз.Вот пример кода для запуска приложения, которое называется приложением входа в систему.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"           "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>RunAtLoad</key>
<true/>
<key>Label</key>
<string>com.apple.LoginApp</string>
<key>Program</key>
<string>/Library/Log Files/LoginApp.app/Contents/MacOS/LoginApp</string>
<key>onDemand</key>
<false/>
</dict>
</plist>

Надеюсь, это поможет

0 голосов
/ 20 сентября 2010

Я вижу две проблемы: основная из них заключается в том, что у вас есть <key>OnDemand</key><false/>, что говорит launchd, что агент должен быть в живых (и это, кажется, переопределяет <key>KeepAlive</key><false/>, что означает с точностью до наоборот). Вторая проблема заключается в том, что перед именем ключа в <key> LaunchOnlyOnce</key><true/> есть пробел. Простое решение: удалите ключи OnDemand и LaunchOnlyOnce, и все должно работать нормально.

...