2010-09-19 7 views
0

Я хотел бы запускать приложение каждый раз при входе пользователя в систему.LaunchAgents for GUI app

Я добавил файл 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> 

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

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

ответ

2

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

Видимо kLSSharedFileListSessionLoginItems устарела (OS X 10.11) уже и Apple, предполагают, что с помощью запуска агентов является лучшей практикой – gbdavid

0

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

+0

Благодаря Гордон и Брайан, – David

+0

LSSharedFileListRef возможно лучше проконтролирован но он не поддерживается в 10.4, и мое приложение должно работать на 10.4. Я фиксировал plist в соответствии с процедурой Гордона, и он работает, однако приложение не запускается для всех пользователей на одной машине. Если I Fast User Switch новый сеанс не запускает мое приложение ... – David

+0

Есть ли обходной путь? Спасибо, Дэвид – David

0

удалить ключ 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> 

Надеется, что это помогает