如何使用Objective-C(Mac平台)检测应用程序是否已打开或启动
嘿,我来帮你搞定在Mac上用Objective-C检测指定应用的两个状态——当前是否处于打开运行状态,以及这个应用是否已经可以被启动(也就是是否已安装)。下面分两种情况详细说:
一、检测应用是否处于打开运行状态
要判断某个应用当前是不是正在跑着,最靠谱的方式是用NSWorkspace类——它是Mac系统里负责管理桌面、应用启动/运行状态的核心类。我们可以通过应用的Bundle ID来匹配(比如Safari的Bundle ID是com.apple.Safari),这比用应用名称可靠多了,毕竟名称可能会因为本地化或者重名出问题。
直接上代码:
#import <Cocoa/Cocoa.h> // 传入目标应用的Bundle ID,返回是否正在运行 BOOL isApplicationRunning(NSString *targetBundleID) { // 获取NSWorkspace的共享实例 NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; // 获取当前所有正在运行的应用列表 NSArray<NSRunningApplication *> *runningApps = [workspace runningApplications]; // 遍历列表匹配Bundle ID for (NSRunningApplication *app in runningApps) { if ([app.bundleIdentifier isEqualToString:targetBundleID]) { return YES; } } return NO; } // 调用示例 int main(int argc, const char * argv[]) { @autoreleasepool { BOOL isSafariRunning = isApplicationRunning(@"com.apple.Safari"); if (isSafariRunning) { NSLog(@"Safari 当前正在运行 🚀"); } else { NSLog(@"Safari 目前没在运行 😴"); } } return 0; }
如果实在只有应用名称(比如"Safari"),也可以用localizedName来匹配,但还是强烈建议用Bundle ID:
// 不推荐,仅作备选 if ([app.localizedName isEqualToString:@"Safari"]) { // ... }
二、检测应用是否已被安装(可启动状态)
这里的“已被启动”我默认理解为应用已经安装在系统中,可以被启动——毕竟如果应用都没安装,肯定没法启动嘛。同样用NSWorkspace,它提供了直接查找应用路径的方法:
#import <Cocoa/Cocoa.h> // 传入Bundle ID,返回应用是否已安装(可启动) BOOL isApplicationInstalled(NSString *targetBundleID) { NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; // 根据Bundle ID获取应用的URL,如果存在则返回非nil NSURL *appURL = [workspace URLForApplicationWithBundleIdentifier:targetBundleID]; return (appURL != nil); } // 调用示例 int main(int argc, const char * argv[]) { @autoreleasepool { BOOL isSafariInstalled = isApplicationInstalled(@"com.apple.Safari"); if (isSafariInstalled) { NSLog(@"Safari 已安装,可以启动 📦"); } else { NSLog(@"Safari 未安装,没法启动 ❌"); } } return 0; }
补充:如果要检测应用是否曾经被启动过
要是你说的“已被启动”是指这个应用曾经被用户打开过,那就要读取系统的启动记录了。系统会把最近启动的应用存在~/Library/Preferences/com.apple.LaunchServices.plist的LSRecentApplications数组里,我们可以解析这个plist来查找目标应用的Bundle ID。不过这个方法有局限性:不同用户的记录是分开的,而且如果用户清理过这个文件,记录就没了,系统版本更新也可能改变plist结构。
示例代码参考:
#import <Cocoa/Cocoa.h> BOOL hasApplicationBeenLaunched(NSString *targetBundleID) { NSString *plistPath = [@"~/Library/Preferences/com.apple.LaunchServices.plist" stringByExpandingTildeInPath]; NSDictionary *launchServicesDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; if (!launchServicesDict) return NO; NSArray *recentApps = launchServicesDict[@"LSRecentApplications"]; for (NSDictionary *appInfo in recentApps) { NSString *appBundleID = appInfo[@"LSHandlerRoleAll"]; if ([appBundleID isEqualToString:targetBundleID]) { return YES; } } return NO; }
内容的提问来源于stack exchange,提问作者lbwnb123
相关产品推荐
相关产品推荐

