objective-c - macOS:检测所有应用程序启动,包括后台应用程序?
问题描述
新手来了 我正在尝试为应用程序启动创建一个小型侦听器,并且我已经有了这个:
// almon.m
#import <Cocoa/Cocoa.h>
#import <stdio.h>
#include <signal.h>
@interface almon: NSObject {}
-(id) init;
-(void) launchedApp: (NSNotification*) notification;
@end
@implementation almon
-(id) init {
NSNotificationCenter * notify
= [[NSWorkspace sharedWorkspace] notificationCenter];
[notify addObserver: self
selector: @selector(launchedApp:)
name: @"NSWorkspaceWillLaunchApplicationNotification"
object: nil
];
fprintf(stderr,"Listening...\n");
[[NSRunLoop currentRunLoop] run];
fprintf(stderr,"Stopping...\n");
return self;
}
-(void) launchedApp: (NSNotification*) notification {
NSDictionary *userInfo = [notification userInfo]; // read full application launch info
NSString* AppPID = [userInfo objectForKey:@"NSApplicationProcessIdentifier"]; // parse for AppPID
int killPID = [AppPID intValue]; // define integer from NSString
kill((killPID), SIGSTOP); // interrupt app launch
NSString* AppPath = [userInfo objectForKey:@"NSApplicationPath"]; // read application path
NSString* AppBundleID = [userInfo objectForKey:@"NSApplicationBundleIdentifier"]; // read BundleID
NSString* AppName = [userInfo objectForKey:@"NSApplicationName"]; // read AppName
NSLog(@":::%@:::%@:::%@:::%@", AppPID, AppPath, AppBundleID, AppName);
}
@end
int main( int argc, char ** argv) {
[[almon alloc] init];
return 0;
}
// build: gcc -Wall almon.m -o almon -lobjc -framework Cocoa
// run: ./almon
注意:当我构建它时,它会运行良好,但是如果您在 High Sierra 上使用 Xcode 10 进行构建,您会收到ld
警告,但是您可以忽略这些警告。
我的问题:有没有办法检测后台应用程序的启动,例如菜单栏应用程序,如粘度等?苹果这么说
系统不会为后台应用程序或文件中包含
LSUIElement
密钥的应用程序发布 [NSWorkspaceWillLaunchApplicationNotification]Info.plist
。如果您想知道所有应用程序(包括后台应用程序)何时启动或终止,请使用键值观察来监控该runningApplications
方法返回的值。
我至少会尝试向侦听器添加对后台应用程序等的支持,但我不知道该怎么做。有任何想法吗?
解决方案
正如文档所建议的,您使用 Key-Value Observing 来观察runningApplications
共享工作区对象的属性:
static const void *kMyKVOContext = (void*)&kMyKVOContext;
[[NSWorkspace sharedWorkspace] addObserver:self
forKeyPath:@"runningApplications"
options:NSKeyValueObservingOptionNew // maybe | NSKeyValueObservingOptionInitial
context:kMyKVOContext];
然后,您将实现观察方法(使用 Xcode 的现成代码段):
- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
if (context != kMyKVOContext)
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if ([keyPath isEqualToString:@"runningApplications"])
{
<#code to be executed when runningApplications has changed#>
}
}
推荐阅读
- docker - 构建错误。无法获取 http://deb.debian.org/debian/dists/jessie-updates/main/binary-amd64/Packages
- scala - 我想在 Scala 中将 org.apache.spark.rdd.RDD[(Any, scala.collection.immutable.Iterable[String])] 展平为 String
- reactjs - 托管在 Firebase 上时,React 路由器不会路由流量
- java - 如何使用 Jsonb 库从 Postgres 读取 jsonb
- mpandroidchart - mpAndroidChart:Xaxis.setPosition 到 Bottom_Inside 在 HorizontalBarChart 上不起作用
- javascript - 使用 Next.js 动态导入节点模块
- java - 从文本文件中提取分离的代码并将其存储到数组中以供进一步使用
- python - 用不同的字符串结尾搜索相同的字符串开头
- python - 在 pythonista Objc_util 中使用 UINotificationFeedbackGenerator
- java - ARCore – 禁用 ModelRenderable 的移动