Cocoa -- 添加和移除开机启动项

Cocoa -- 添加和移除开机启动项,第1张

概述一 写plist到~/Library/LaunchAgents/ 目录下 [plain]  view plain copy // 配置开机默认启动   -(void)installDaemon{       NSString* launchFolder = [NSString stringWithFormat:@"%@/Library/LaunchAgents",NSHomeDirectory()  pList~/library/LaunchAgents/ 目录下

[plain]  view plain copy // 配置开机默认启动   -(voID)installDaemon{       Nsstring* launchFolder = [Nsstring stringWithFormat:@"%@/library/LaunchAgents",NSHomeDirectory()];       Nsstring * boundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:(Nsstring *)kcfBundleIDentifIErKey];        Nsstring* dstLaunchPath = [launchFolder stringByAppendingFormat:@"/%@.pList",boundleID];       NSfileManager* fm = [NSfileManager defaultManager];       BOol isDir = NO;       //已经存在启动项中,就不必再创建       if ([fm fileExistsAtPath:dstLaunchPath isDirectory:&isDir] && !isDir) {           return;       }       //下面是一些配置       NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];       NSMutableArray* arr = [[NSMutableArray alloc] init];       [arr addobject:[[NSBundle mainBundle] executablePath]];       [arr addobject:@"-runMode"];       [arr addobject:@"autoLaunched"];       [dict setobject:[NSNumber numberWithBool:true] forKey:@"RunAtLoad"];       [dict setobject:boundleID forKey:@"Label"];       [dict setobject:arr forKey:@"ProgramArguments"];       isDir = NO;       if (![fm fileExistsAtPath:launchFolder isDirectory:&isDir] && isDir) {           [fm createDirectoryAtPath:launchFolder withIntermediateDirectorIEs:NO attributes:nil error:nil];       }       [dict writetofile:dstLaunchPath atomically:NO];       [arr release];  arr = nil;       [dict release]; dict = nil;   }  


关于启动项的配置可以去开发文档搜索:Creating launchd Daemons and Agents

取消开机启动则只要删除~/library/LaunchAgents/ 目录下相应的pList文件即可。

copy // 取消配置开机默认启动   -(voID)unInstallDaemon{       BOol isDir = NO;       NSfileManager* fm = [NSfileManager defaultManager];           return;       Nsstring * boundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:(Nsstring *)kcfBundleIDentifIErKey];        Nsstring* srcLaunchPath = [launchFolder stringByAppendingFormat:@"/%@.pList",boundleID];       [fm removeItemAtPath:srcLaunchPath error:nil];   }  

二.使用LoginItemSAE 

在开发文档中搜索LoginItemSAE即可搜到它的源码,包含LoginItemSAE.cLoginItemSAE.h两个文件。其原理是写配置信息到~/library/Preferences/com.apple.loginitems.pList 文件。打开com.apple.loginitems.pList文件找到CustomListItems那一项,展开就可以看到开机启动项的一些信息(包括app名称,所在路径。。。)


图1:com.apple.loginitems.pList 开机启动项内容

下面简单介绍下LoginItemSAE.h 中的几个API

copy //返回开机启动项列表,传入itemsPtr地址即可,   extern Osstatus liAEcopyLoginItems(CFArrayRef *itemsPtr);  
copy //添加开机启动项,hIDeIt参数一般是传 NO   extern Osstatus liAEAddURLAtEnd(CFURLRef item,     Boolean hIDeIt);  


copy //移除开机启动项   extern Osstatus liAERemove(CFIndex itemIndex);  

是不是觉得上面的接口不是很好用呢,特别是移除启动项的那个接口,必须得知道要移除的index,如果能根据文件路径移除就好了。下面用Objective-C语法重新封装这几个接口,更方便调用。

copy #import "UKLoginItemRegistry.h"         @implementation UKLoginItemRegistry   +(NSArray*) allLoginItems   {       NSArray*    itemsList = nil;       Osstatus    err = liAEcopyLoginItems( (CFArrayRef*) &itemsList );   // Take advantage of toll-free brIDging.       if( err != noErr )       {           NSLog(@"Couldn't List login items error %ld", err);           return nil;              return [itemsList autorelease];   }   +(BOol)     addLoginItemWithPath: (Nsstring*)path hIDeIt: (BOol)hIDe   {       NSURL*  url = [NSURL fileURLWithPath: path];              return [self addLoginItemWithURL: url hIDeIt: hIDe];   }   //根据文件路径移除启动项   +(BOol)     removeLoginItemWithPath: (Nsstring*)path       int     IDx = [self indexForLoginItemWithPath: path];       return (IDx != -1) && [self removeLoginItemAtIndex: IDx];   // Found item? Remove it and return success flag. Else return NO.   +(BOol)     addLoginItemWithURL: (NSURL*)url hIDeIt: (BOol)hIDe         // Main bottleneck for adding a login item.       Osstatus err = liAEAddURLAtEnd( (CFURLRef) url, hIDe ); // CFURLRef is toll-free brIDged to NSURL.           NSLog(@"Couldn't add login item error %ld", err);       return( err == noErr );   +(BOol)     removeLoginItemAtIndex: (int)IDx            // Main bottleneck for getting rID of a login item.       Osstatus err = liAERemove( IDx );       if( err != noErr )           NSLog(@"Couldn't remove login intem error %ld",92); line-height:18px">     return( err == noErr );   +(int)      indexForLoginItemWithURL: (NSURL*)url       // Main bottleneck for finding a login item in the List.       NSArray*        loginItems = [self allLoginItems];       NSEnumerator*   enny = [loginItems objectEnumerator];       NSDictionary*   currLoginItem = nil;       int             x = 0;       while(( currLoginItem = [enny nextObject] ))       {           if( [[currLoginItem objectForKey: UKLoginItemURL] isEqualTo: url] )               return x;                      x++;       return -1;   +(int)      indexForLoginItemWithPath: (Nsstring*)path       NSURL*  url = [NSURL fileURLWithPath: path];       return [self indexForLoginItemWithURL: url];   +(BOol)     removeLoginItemWithURL: (NSURL*)url       int     IDx = [self indexForLoginItemWithURL: url];       return (IDx != -1) && [self removeLoginItemAtIndex: IDx];   // Found item? Remove it and return success flag. Else return NO.   @end  

上面的代码是不是觉得亲切多了啊?

不过这几个接口有点缺陷:只能用i386来编译,用x86_64编译会报错的。


. 使用LaunchServices修改启动项

可以使用LaunchServices/LSSharedfileList.h 里面的方法来更改启动项,但是这些方法只支持10.5及以上的系统。下面简单的介绍下这些方法。

copy //这个方法返回启动项列表   extern LSSharedfileListRef   LSSharedfileListCreate(                          CFAllocatorRef   inAllocator,                          CFStringRef      inListType,                          CFTypeRef        ListOptions)  
copy //添加新的启动项   extern LSSharedfileListItemRef LSSharedfileListInsertItemURL(                                 LSSharedfileListRef       inList,92); line-height:18px">                               LSSharedfileListItemRef   insertAfterThisItem,255); color:inherit; line-height:18px">                               CFStringRef               indisplayname,92); line-height:18px">                               IconRef                   inIconRef,255); color:inherit; line-height:18px">                               CFURLRef                  inURL,92); line-height:18px">                               CFDictionaryRef           inPropertIEsToSet,255); color:inherit; line-height:18px">                               CFArrayRef                inPropertIEsToClear)  

copy //移除启动项   extern Osstatus LSSharedfileListItemRemove(                              LSSharedfileListRef       inList,92); line-height:18px">                            LSSharedfileListItemRef   inItem)  

copy //最后一个方法用来解析启动项的 URL,用来检索启动项列表里的东西   extern Osstatus LSSharedfileListItemResolve(                               LSSharedfileListItemRef   inItem,92); line-height:18px">                             UInt32                    inFlags,255); color:inherit; line-height:18px">                             CFURLRef *                outURL,92); line-height:18px">                             FSRef *                   outRef)  


使用下面两个方法来封装上面的这些API,使更易于使用。你也可以改成传入app路径添加启动项。- (voID) addAppAsLoginItem:(Nsstring *)appPath,把这句Nsstring * appPath = [[NSBundle mainBundle] bundlePath];注视掉就行了。

copy -(voID) addAppAsLoginItem{       Nsstring * appPath = [[NSBundle mainBundle] bundlePath];       // This will retrIEve the path for the application       // For example, /Applications/test.app       CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath];        // Create a reference to the shared file List.       // We are adding it to the current user only.       // If we want to add it all users, use       // kLSSharedfileListGlobalLoginItems instead of       //kLSSharedfileListSessionLoginItems       LSSharedfileListRef loginItems = LSSharedfileListCreate(NulL,92); line-height:18px">                                                             kLSSharedfileListSessionLoginItems, NulL);       if (loginItems) {           //Insert an item to the List.           LSSharedfileListItemRef item = LSSharedfileListInsertItemURL(loginItems,92); line-height:18px">                                                                      kLSSharedfileListItemLast, NulL,255); color:inherit; line-height:18px">                                                                      url, NulL);           if (item){               CFRelease(item);           }       CFRelease(loginItems);   -(voID) deleteAppFromLoginItem{       Nsstring * appPath = [[NSBundle mainBundle] bundlePath];       // This will retrIEve the path for the application       // For example, /Applications/test.app       CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath];        // Create a reference to the shared file List.       LSSharedfileListRef loginItems = LSSharedfileListCreate(NulL,255); color:inherit; line-height:18px">                                                             kLSSharedfileListSessionLoginItems,92); line-height:18px">         UInt32 seedValue;           //RetrIEve the List of Login Items and cast them to           // a NSArray so that it will be easIEr to iterate.           NSArray  *loginItemsArray = (NSArray *)LSSharedfileListcopySnapshot(loginItems, &seedValue);           int i = 0;           for(i ; i< [loginItemsArray count]; i++){               LSSharedfileListItemRef itemRef = (LSSharedfileListItemRef)[loginItemsArray                                                                           objectAtIndex:i];               //Resolve the item with URL               if (LSSharedfileListItemResolve(itemRef, 0, (CFURLRef*) &url, NulL) == noErr) {                   Nsstring * urlPath = [(NSURL*)url path];                   if ([urlPath compare:appPath] == NSOrderedSame){                       LSSharedfileListItemRemove(loginItems,itemRef);                   }               }           }           [loginItemsArray release];   }  

详情请打开:http://cocoatutorial.grapewave.com/2010/02/creating-andor-removing-a-login-item/


使用NSUserDefaults修改启动项

下面通过分类给NSUserDefaults添加新的方法。

copy @implementation NSUserDefaults (Additions)   - (BOol)addApplicationTologinItems:(Nsstring *)path {       NSDictionary *domain = [self persistentDomainForname:@"loginwindow"];       NSArray *apps = [domain objectForKey:@"autoLaunchedApplicationDictionary"];       NSArray *matchingApps = [apps filteredArrayUsingPredicate:[nspredicate predicateWithFormat:@"Path CONTAINS %@", path]];       if ([matchingApps count] == 0) {           NSMutableDictionary *newDomain = [domain mutablecopy];           NSMutableArray *newApps = [[apps mutablecopy] autorelease];           NSDictionary *app = [NSDictionary dictionaryWithObjectsAndKeys:path, @"Path", [NSNumber numberWithBool:NO], @"HIDe", nil];           [newApps addobject:app];           [newDomain setobject:newApps forKey:@"autoLaunchedApplicationDictionary"];           [self setPersistentDomain:newDomain forname:@"loginwindow"];           return [self synchronize];       return NO;   - (BOol)removeApplicationFromLoginItems:(Nsstring *)name {       NSArray *newApps = [apps filteredArrayUsingPredicate:[nspredicate predicateWithFormat:@"not Path CONTAINS %@", name]];       if (![apps isEqualToArray:newApps]) {           [newDomain setobject:newApps forKey:@"autoLaunchedApplicationDictionary"];           [self setPersistentDomain:newDomain forname:@"loginwindow"];           return [self synchronize];       return NO;   @end   总结

以上是内存溢出为你收集整理的Cocoa -- 添加和移除开机启动项全部内容,希望文章能够帮你解决Cocoa -- 添加和移除开机启动项所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1056445.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存