美文网首页
Cocoa -- 添加和移除开机启动项

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

作者: 清蘂翅膀的技术 | 来源:发表于2021-01-16 02:28 被阅读0次

方法一:

1、写plist到~/Library/LaunchAgents/目录下

// 配置开机默认启动

    -(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; 

    }

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

// 取消配置开机默认启动  -(void)unInstallDaemon{ 

        NSString* launchFolder = [NSString stringWithFormat:@"%@/Library/LaunchAgents",NSHomeDirectory()]; 

        BOOL isDir = NO; 

        NSFileManager* fm = [NSFileManager defaultManager]; 

        if(![fm fileExistsAtPath:launchFolder isDirectory:&isDir] && isDir) { 

            return; 

        } 

        NSString * boundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleIdentifierKey]; 

        NSString* srcLaunchPath = [launchFolder stringByAppendingFormat:@"/%@.plist",boundleID]; 

        [fm removeItemAtPath:srcLaunchPath error:nil]; 

    } 

方法二:

Service Management framework 在系统的登录项中是不可见的。只有卸载App才能移除登录项

1.这里认为你已经有了一个将要被启动的主工程与主Target

我的app名为iSimulator, ServiceManagement.framework

2.在主工程添加自动启动Target

命名最好是主Target名+Helper    比如iSimulatorHelper

3.配置XXXHelper

删除XXXHelper中的windows与Menu,让它没有可展示的Window。

设置XXXHelper的Info中Application is background only为YES

设置XXXHelper中Build Setting下skip install为YES

4.在主APP Target中添加CopyFile到Contents/Library/LoginItems

随后点击+ 把helper app添加进来.

在主APP Target中设置Build Setting 下Strip Debug Symbols During Copy为NO, 这个是默认的为No

分别开启主APP Target和Helper的App Sandbox

代码

主APP Target的自启动开关实现

-(void)daemon:(Boolean)install{

    NSString *helperPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Library/LoginItems/iSimulatorHelper.app"];

    if (![[NSFileManager defaultManager] fileExistsAtPath:helperPath])

    {

        return;

    }

    NSURL *helperUrl = [NSURL fileURLWithPath:helperPath];

    // Registering helper app

    if (LSRegisterURL((__bridge CFURLRef)helperUrl, true) != noErr)

    {

        NSLog(@"LSRegisterURL failed!");

    }

    // Setting login

    // com.xxx.xxx为Helper的BundleID,ture/false设置开启还是关闭

    if (!SMLoginItemSetEnabled((CFStringRef)@"org.skyfox.iSimulatorHelper",install))

    {

        NSLog(@"SMLoginItemSetEnabled failed!");

    }

    NSString *mainAPP = [NSBundle mainBundle].bundleIdentifier?:@"org.skyfox.iSimulator";

    BOOL alreadRunning = NO;

    NSArray *runnings = [NSWorkspace sharedWorkspace].runningApplications;

    for (NSRunningApplication *app in runnings) {

        if ([app.bundleIdentifier isEqualToString:mainAPP]) {

            alreadRunning = YES;

            break;

        }

    }

    if (alreadRunning) {

        [[NSDistributedNotificationCenter defaultCenter]postNotificationName:@"killme" object:[NSBundle mainBundle].bundleIdentifier];

    }

}

Helper的AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    NSString *mainAPP = @"org.skyfox.iSimulator";

//    NSArray *runningArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:mainAPP];

    BOOL alreadRunning = NO;

    NSArray *runnings = [NSWorkspace sharedWorkspace].runningApplications;

    for (NSRunningApplication *app in runnings) {

        if ([app.bundleIdentifier isEqualToString:mainAPP]) {

            alreadRunning = YES;

            break;

        }

    }

    if (!alreadRunning) {

        [[NSDistributedNotificationCenter defaultCenter] addObserver:self

                                                            selector:@selector(terminate) name:@"killme" object:mainAPP];

        NSString *appPath = [[NSBundle mainBundle] bundlePath];

        appPath = [appPath stringByReplacingOccurrencesOfString:@"/Contents/Library/LoginItems/iSimulatorHelper.app" withString:@""];

        appPath = [appPath stringByAppendingPathComponent:@"Contents/MacOS/iSimulator"];

        if (![[NSFileManager defaultManager] fileExistsAtPath:appPath])

        {

            return;

        }

        [[NSWorkspace sharedWorkspace] launchApplication:appPath];

    }else{

        [self terminate];

    }

}

- (void)terminate{

    [NSApp terminate:nil];

}

判断是不是开机自启动

- (BOOL)isStartAtLogin {

    NSDictionary *dict = (__bridge NSDictionary*)SMJobCopyDictionary(kSMDomainUserLaunchd,

                                                            CFSTR("org.skyfox.iSimulatorHelper"));

    BOOL contains = (dict!=NULL);

    return contains;

}

相关文章

网友评论

      本文标题:Cocoa -- 添加和移除开机启动项

      本文链接:https://www.haomeiwen.com/subject/pfwgaktx.html