- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在一段时间后终止某些应用程序的执行。我正在轮询 NSWorkspace 的 runningApplications 是否缺少可观察的内容(如果应用程序正在运行,它是否会通知任何内容?)
我的问题是应用程序只是有时会终止,有时它们会在应该关闭的时间过后几秒钟(根据内部计时器),有时它们根本不会终止!
我尝试同时使用 terminate 和 forceTerminate 方法。
在代码片段中,apps_ 是一个包含应用程序名称的字符串向量。它由另一个线程定期更新,并在运行以下代码之前接收其数据。它们都在 es_handler_block_t
中运行NSArray<NSRunningApplication *> *running_apps = [NSWorkspace sharedWorkspace].runningApplications;
for (const auto &app_ : apps_) {
//std::cout << app_ << "\n";
for (NSRunningApplication *app in running_apps) {
if ([[NSString stringWithUTF8String:app_.c_str()] isEqualToString:[app.executableURL lastPathComponent]] ) {
std::string app_name = [[app.executableURL absoluteString] UTF8String];
std::cout << "Terminating app " << app_name << "\n";
bool res_f = [app forceTerminate];
bool res_t = [app terminate];
LOG_DBG("Force terminate: %d", res_f);
LOG_DBG("Terminate: %d", res_t);
break;
}
}
}
我在 runningApplications 文档中读到“此属性只会在主运行循环以公共(public)模式运行时发生变化”。什么意思?
我想这与 runningApplication 的轮询有关,因为在上面的代码中插入一个断点(在 if 检查之前),然后立即恢复执行会杀死本来仍在运行的应用程序。
我没有阻止主要功能。我只有一个框架的端点安全类,网络是在其他线程上完成的,我用 NSApplicationMain(argc, argv);
return
可能是什么问题?谢谢。
编辑:我正在利用 Cocoa Framework 创建一个仅显示在系统托盘中且具有 root 权限的代理。使用 Endpoint Security Framework 成功阻止应用程序启动,但我没有找到一种可靠的方法来终止已经运行且每次都能正常运行的应用程序。
后期编辑:我设法将观察者添加到 [[NSWorkspace sharedWorkspace] notificationCenter]
,但是我应该为正在运行的应用程序订阅什么通知?我试过隐藏,但如果用户只是点击红色窗口按钮,它就不起作用,只有当他从扩展坞中隐藏应用程序时。但即使用户与正在运行的应用程序之间没有交互,我仍然想关闭它。
最佳答案
在 macOS 上可靠地终止应用程序取决于很多因素,例如:
例如,您的应用程序可能被允许终止一个应用程序,但是,例如,如果您使用 KeepAlive
命令终止由 launchd
启动的进程,使用像这样的 plist:
<?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>
<true/>
<key>Label</key>
<string>com.bundleidentifierOf.AnUnquitabbleApp</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/the/AnUnquitableApp</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
您会大吃一惊,因为在您尝试这样做的那一刻,launchd
会立即重新启动它,看起来好像应用程序没有被杀死,但它确实被杀死了。当您每次尝试终止应用程序时,其 PID 都会发生变化,您会看到该应用程序已重新启动。
您可以使用以下命令检查:
ps -ax
在终端中列出在您的 Mac 上运行的所有进程。如果您想知道应用程序是否正在运行,请使用:
ps -ax | grep "AnUnquitableAppNameHere"
然后你可以通过使用它的 PID 来杀死它
kill <PID>
这将帮助您确定哪些应用可以使用简单的 QUIT 信号终止,哪些您需要使用更强的信号来终止它们,哪些是不可终止的,因为终止它们需要您的应用可能不需要的特权或权利有。阅读 ps
和 kill
的手册页以了解有关您的目标应用的更多信息。
在 macOS 上还有许多其他方法可以获得持久性,如果您想了解如何可靠地退出应用程序,您首先需要了解它们是如何获得持久性的。
例如,如果用户具有管理员/ super 用户权限,则可以通过在/Library/LaunchDaemons
中安装守护进程来获得持久性。如果您的应用没有 root 权限,则您不太可能终止该进程。
除了 launchd
plist 之外,应用程序保持持久性的另一种方法是,例如,有一个后台应用程序,一旦主应用程序被迫退出,它就会重新启动主应用程序。一个例子是,如果你使用 kill
来杀死最新版本的 Microsoft Word
你会看到它会被这样一个会提示 Word 的助手重新启动
被迫退出。
杀死应用程序的最好方法实际上是向它发送一个 Quit Apple Event,这就是我通常做的。
我不想让你气馁,但你想要实现的目标比一开始看起来要困难得多。即使您成功了,请记住,用户可能会终止您的应用程序,这将打败您想要实现的目标,除非它通过启动的 plist 或其他形式的持久性保持事件。
现在,如果您想观察哪些应用程序在没有轮询的情况下被杀死或启动,我绝对建议您阅读 TN2050 .
现在回答您的具体问题:
"this property will only change when the main run loop runs in a common mode"
这意味着您需要有一个运行循环来更新 NSRunningApplication
。如果您有 GUI 应用程序,那么已经为您安装了这样的循环。如果你的应用程序是 CLI,那么这个是没有安装的,你需要自己安装这样一个运行循环。如果您使用的是 Objective-C,那么您可以按照此 question 中的建议进行操作.
因此,您要实现的目标有很多注意事项,您需要在继续之前了解它们。
关于objective-c - NSWorkspace 的 runningApplications 有多可靠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62118302/
我已经实现了一个必须等待特定进程完成的类(通过使用 NSWorkspace openFile:withApplication 启动)。 我尝试过[[NSWorkspace sharedWorksp
我想在一段时间后终止某些应用程序的执行。我正在轮询 NSWorkspace 的 runningApplications 是否缺少可观察的内容(如果应用程序正在运行,它是否会通知任何内容?) 我的问题是
有没有办法过滤由 [NSWorkspace runningApplications] 给出的应用程序列表来隐藏所有守护进程等,而无需手动检查每个应用程序的 plist 中的 UIAgent key ?
NSArray *activeApps = [[NSWorkspace sharedWorkspace] runningApplications]; 返回正在运行的应用程序和代理,但我看不到正在运行的
一段时间以来,我一直在仔细研究 Apple 文档,但还没有找到可以从 AppKit 中的 NSWorkspace 获取的与 sharedWorkspace 对象等效的 iOS 对象。基本上,我只想要其
我是一名优秀的程序员,十分优秀!