我想在经过一段时间后终止某些应用程序的执行。我正在轮询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文档中看到,“ 仅当主运行循环以通用模式运行时,此属性才会更改”。这是什么意思?
我想这与runningApplication的轮询有关,因为在上面的代码中(在if检查之前)插入一个断点,然后立即恢复执行将杀死本来可以继续运行的应用程序。
我没有阻止主要功能。我只有该框架的Endpoint Security类,联网是在其他线程上完成的,并且我将return
与NSApplicationMain(argc, argv);
可能是什么问题?谢谢。
可靠地在macOS上终止应用程序取决于很多因素,例如:
例如,可能允许您的应用终止一个应用,但是,例如,如果您使用[p0]并使用如下plist杀死了launchd
启动的进程:
kept alive
[您将感到惊讶,因为尝试这样做的那一刻,<?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>
将立即重新启动它,似乎该应用程序没有被杀死,但是确实被杀死了。您可以看到,每次您尝试将其杀死时,应用程序的PID都会重新启动。
您可以使用以下命令进行检查:
launchd
在终端中列出Mac上正在运行的所有进程。如果您想知道某个应用程序是否正在运行,请使用:
ps -ax
然后您可以通过将其PID与-一起杀死它>
ps -ax | grep "AnUnquitableAppNameHere"
这将帮助您确定您可以通过简单的QUIT信号杀死哪些应用程序,您需要使用更强的信号来终止哪些应用程序,而哪些是不可行的,因为杀死它们需要您的应用程序可能没有的特权或权利。阅读kill <PID>
和ps
的手册页,以了解有关目标应用程序的更多信息。
[macOS上还有许多其他方法来获得持久性,如果您想了解如何可靠地退出应用程序,则首先需要了解它们如何获得持久性。
例如,如果用户具有管理员/超级用户特权,则可以通过在kill
中安装守护程序来获得持久性。如果您的应用没有root权限,则您不太可能杀死该进程。
例如,除了/Library/LaunchDaemons
plist外,应用程序还可以保持持久性的另一种方法是拥有一个后台应用程序,该应用程序将在主应用程序被迫退出后立即重新启动。一个例子是,如果您使用launchd
杀死kill
的最新版本,您会看到它会被这样的助手重新启动,该助手会抱怨Microsoft Word
被迫退出。
杀死应用程序的最好方法实际上是向其发送退出苹果事件,这是我通常要做的。
我不想让您灰心,但是您想要实现的目标比最初看起来要困难得多。而且即使您成功了,也要记住,用户可能会杀死您的应用程序,并且会破坏您试图实现的目标,除非已通过启动的plist或其他持久化方式使该应用程序存活下来。
现在,如果您想观察哪些应用程序在没有轮询的情况下被杀死或启动,我绝对建议您阅读Word
。
现在回答您的特定问题:
“仅当主运行循环在共模“
这意味着您需要有一个运行循环才能更新TN2050。如果您有GUI应用程序,则已经为您安装了这样的循环。如果您的应用程序是CLI,则不会安装此程序,您需要自己安装这样的运行循环。如果您使用的是Objective-C,则可以按照此
NSRunningApplication
中的建议进行操作。因此,您要实现的目标有很多警告,在继续之前,您需要了解它们。