2010-09-19 110 views
0

我想每次用户登录时启动我的应用程序。LaunchAgent for GUI应用程序

我添加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> 

一切看起来OK,应用程序被加载,但是当我离开我的应用程序是通过的launchd服务推出回来。

我应该在我的plist文件中添加/修改哪个键,以防止我的应用程序不断重新启动。

回答

2

如果您想在登录时启动常规应用程序,我建议使用LaunchServices共享文件列表API而不是launchd。您不必安装启动的plist,只需使用此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)已经和苹果公司建议,使用发射剂是一种更好的做法 – gbdavid 2015-10-23 07:59:18

0

我看到两个问题:主要的是你有<key>OnDemand</key><false/>,它告诉launchd代理需要我保持活着(这似乎是重写<key>KeepAlive</key><false/>,这意味着完全相反)。第二个问题是您在<key> LaunchOnlyOnce</key><true/>的密钥名称前有一个空格。简单的解决方案:删除OnDemand和LaunchOnlyOnce键,它应该工作正常。

+0

感谢戈登和布莱恩, – David 2010-09-20 14:58:52

+0

LSSharedFileListRef也许是更好的controled但它在10.4不支持,我的应用程序必须在10.4上运行。我根据Gordon的程序修复了plist,并且它可以工作,但是对于同一台机器上的所有用户,不会启动应用程序。如果我快速用户切换新会话不启动我的应用程序.... – David 2010-09-20 15:01:00

+0

是否有任何解决方法?谢谢大卫 – David 2010-09-20 15:01:18

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> 

希望这有助于