NSWorkspace的runningApplications有多可靠?

问题描述 投票:3回答:1

我想在经过一段时间后终止某些应用程序的执行。我正在轮询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类,联网是在其他线程上完成的,并且我将returnNSApplicationMain(argc, argv);

可能是什么问题?谢谢。

objective-c macos cocoa objective-c++ nsworkspace
1个回答
1
投票

可靠地在macOS上终止应用程序取决于很多因素,例如:

  1. 权利
  2. 如何启动应用程序
  3. 如果有任何后台应用程序使主应用程序崩溃或被其他进程退出,则该应用程序仍可正常运行。>
  4. 例如,可能允许您的应用终止一个应用,但是,例如,如果您使用[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中的建议进行操作。

因此,您要实现的目标有很多警告,在继续之前,您需要了解它们。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.