Как определить, если процесс в пользовательском интерфейсе процесса? - PullRequest
2 голосов
/ 25 сентября 2011

Как я могу получить информацию от процесса, что это процесс пользовательского интерфейса (UI) или не пользовательский интерфейс?

Под процессом пользовательского интерфейса я имею в виду Finder, Dock, сервер System UI или любое другое приложение Mac, которое имеет интерфейс UI и используется Window Server.

Я хочу определить эту информацию изProcessID.

Я использую Mac OS X.

Ответы [ 3 ]

2 голосов
/ 28 сентября 2011

Нет способа определить, основываясь исключительно на PID число , что представляет собой конкретный процесс.Причина этого: идентификаторы процессов назначаются (несколько) последовательно от PID = 1 при запуске, и запуск может быть различным для разных систем.Идентификатор процесса также будет переназначен, если, например, Finder или Dock аварийно завершат работу и должны быть перезапущены.

Если вы можете запустить команду терминала с определенной pid, которая у вас есть, сделайте это:

ps -p <pid> -o ucomm=

Вы получите имя файла процесса, который вы можете проверить по списку тех, которые, как вы знаете, являются процессами пользовательского интерфейса.Например, вот вывод некоторых команд ps в моей системе для моего текущего сеанса входа в систему:

> ps -p 110 -o ucomm=
Dock

> ps -p 112 -o ucomm=
Finder

И следующая команда выдаст вам список процессов в порядке идентификатора процесса, с толькоимя:

> ps -ax -o pid=,ucomm=
   1 launchd
  10 kextd
  11 DirectoryService
     ...

РЕДАКТИРОВАТЬ: Вы можете сделать то, что вы просите, хотя это запутанно. В этом ответе упоминается:

Функция CGWindowListCopyWindowInfo () из CGWindow.h будет возвращать массив словарей, по одному на каждое окно, которое соответствует заданным вами критериям, в том числе в другихПриложения.Он позволяет фильтровать только по окнам над данным окном, окнам под данным окном и «экранным» окнам, но возвращаемый словарь содержит идентификатор процесса для приложения-владельца, который можно использовать для сопоставления окна с приложением.

Если вы можете получить все CGWindow с и соответствующие им pid с, то вы будете знать pid с всех приложений пользовательского интерфейса, даже не запуская ps.

Рахул реализовал следующий код для этого подхода, который он попросил добавить в ответ:

CFArrayRef UiProcesses()
{
    CFArrayRef  orderedwindows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
    CFIndex count = CFArrayGetCount (orderedwindows);
    CFMutableArrayRef uiProcess = CFArrayCreateMutable (kCFAllocatorDefault , count,  &kCFTypeArrayCallBacks);
    for (CFIndex i = 0; i < count; i++)
    {
        if (orderedwindows)
        {
            CFDictionaryRef windowsdescription = (CFDictionaryRef)CFArrayGetValueAtIndex(orderedwindows, i);
            CFNumberRef windowownerpid  = (CFNumberRef)CFDictionaryGetValue (windowsdescription, CFSTR("kCGWindowOwnerPID"));
            CFArrayAppendValue (uiProcess, windowownerpid);

        }
    }
    return uiProcess;
}
0 голосов
/ 28 сентября 2011

На строчках darvidsOn ниже приведен ответ на ваш вопрос.

  CFArrayRef UiProcesses()
    {
        CFArrayRef  orderedwindows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
        CFIndex count = CFArrayGetCount (orderedwindows);
        CFMutableArrayRef uiProcess = CFArrayCreateMutable (kCFAllocatorDefault , count,  &kCFTypeArrayCallBacks);
        for (CFIndex i = 0; i < count; i++)
        {
            if (orderedwindows)
            {
                CFDictionaryRef windowsdescription = (CFDictionaryRef)CFArrayGetValueAtIndex(orderedwindows, i);
                CFNumberRef windowownerpid  = (CFNumberRef)CFDictionaryGetValue (windowsdescription, CFSTR("kCGWindowOwnerPID"));
                CFArrayAppendValue (uiProcess, windowownerpid);

            }
        }
        return uiProcess;
    }

Просто сравните ваш processid с элементами массива, чтобы получить желаемый результат.

0 голосов
/ 25 сентября 2011

Попробуйте следующее.

#include <unistd.h>

  if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO))
    // Process associated with a terminal
  else
    // No terminal - probably UI process
...