如何判断进程是否在OSX上具有图形界面?

时间:2011-10-19 13:39:21

标签: objective-c c macos process

无论如何,我们可以确定该流程是否具有用户界面?任何涉及在屏幕上绘图的东西。

我看了this question,但没有给出正确答案。我在这个过程中。我可以查询一些api,或者某种技术吗?

编辑:我在进程中,我正在进行代码注入。对于非gui应用程序,我想表现出与gui应用程序不同的行为。我不能使用CFBundleGetValueForInfoDictionaryKey()或NSApplicationMain,因为我想保持注入模块的亮度,因此我无法链接这些框架。

1 个答案:

答案 0 :(得分:6)

这在很大程度上取决于你的意思"有一个图形界面。"你是说,"正在显示一个窗口?"或者"有一个停靠图标?"或者"可以访问Aqua上下文,以便它可以显示一个窗口,如果它想要?"或者"与AppKit链接?"

没有停靠栏图标的应用包会将Info.plistLSUIElement设置为" 1"。您可以使用CFBundleGetValueForInfoDictionaryKey()(或者如果您在Objective-C中使用NSBundle等效内容)来获取此内容。这并不意味着应用程序没有GUI,但确实意味着它不会出现在Dock中。许多LSUIElement个应用都有状态项UI。

您还可以使用Info.plist等检查您确实拥有CFBundleCopyBundleURL()。如果你没有Info.plist,那么你就不会成为类似GUI的""程序很可能。 (尽管如此,如果没有这个,可以生成GUI)。

您可以使用弱链接来测试AppKit:

if (NSApplicationMain != NULL) {
  // We're linked with AppKit
}

这是一个相当好的指标,表明你将拥有一个用户界面。但它不会捕获旧的Carbon应用程序。

关于你的意思的更多背景"我在这个过程中"会有所帮助。我假设您是一个框架,并希望GUI应用程序的行为与非GUI应用程序不同?


要检测能够在屏幕上绘图的应用程序,我会检查CoreGraphics是否已链接。这只适用于自10.3以来构建的程序,但应该相当准确(我相信旧的QuickDraw应用程序仍然链接10.3+的Core Graphics,但我没有一个方便检查)。可能最好的方法是对CGColorCreate()进行weak linking check,因为它已经存在了很长时间并且不太可能消失:

extern CGColorRef CGColorCreate(CGColorSpaceRef space, const CGFloat components[]) 
    __attribute__((weak_import));

...
if (CGColorCreate != NULL) {
  // Linked with CoreGraphics. Probably a GUI

当然,事物可以与CoreGraphics链接,并且能够在屏幕上绘图,但从不实际在屏幕上绘图。他们可能会与CoreGraphics联系以进行图像处理。通过查找ApplicationServices可能更准确。您可以针对ApplicationServicesVersionNumber测试NULL,但是没有记录。

这不会捕获X应用程序,因为它们在技术上不会在屏幕上绘制。他们将命令发送到X11.app,这是一个GUI。您是否认为/ usr / X11 / bin / xterm是一个用于此目的的GUI?的/ usr / X11 /斌/ xeyes?

在任何应用中都没有明确的标志,我会在屏幕上画画。#34;我在屏幕上画画。"在屏幕上绘图不是您需要预先声明的内容。在屏幕上绘制的应用程序不必在每次运行时都这样做。通常不可见的应用程序可以选择或偶尔创建状态项。很难想出包含GrowlHelperApp.app,Pages.app和/ usr / X11 / bin / xeyes的单一描述。