Получить список всех процессов windows

Как получить список запущенных процессов?


Автор: Александр Федотов

Опубликовано: 23.10.2001
Исправлено: 13.03.2005
Версия текста: 1.1

Введение

Win32 предоставляет несколько способов перечисления запущенных процессов. К сожалению, нет единого способа, который бы работал на всех Win32-платформах. Программистам приходится комбинировать несколько методов в одной программе, чтобы она работала на всех версиях Windows.

Мы рассмотрим следующие методы:

  • С помощью библиотеки Process Status Helper (PSAPI)
  • С помощью ToolHelp32 API
  • С помощью недокументированной функции ZwQuerySystemInformation
  • Через счетчики производительности
  • С использованием интерфейсов Windows Management Instrumentation

Каждый метод мы будем иллюстрировать с помощью функции, имеющей следующий прототип:

Функция перечисления вызывает для каждого процесса указанную пользовательскую функцию, передавая ей информацию об очередном процессе. Пользователькая функция распоряжается этими данными в соответствии с логикой программы, например, в тестовом приложении для этой статьи, она добавляет очередной элемент в список. Некоторые из рассматриваемых нами методов позволяют перечислить процессы на других компьютеров, поэтому прототип функции содержит параметр pszMachineName, позволяющий задать имя компьютера. Значение NULL для этого параметра означает перечисление процессов на локальном компьютере.

Способ 1. Использование библиотеки Process Status Helper

Библиотека Process Status Helper, известная также под названием PSAPI, предоставляет набор функций, позволяющих получить информацию о процессах и драйверах устройств. Библиотека поставляется в составе Windows 2000/XP и доступна в качестве устанавливаемой компоненты для Windows NT 4.0.

Для перечисления процессов библиотека предоставляет функцию EnumProcesses , которая возвращает массив идентификаторов запущенных процессов. Ниже приведен текст функции EnumProcesses_PsApi , реализующей перечисление процессов с помощью PSAPI.

Обратите внимание, что мы связываемся с PSAPI.DLL динамически, загружая библиотеку с помощью LoadLibrary и получая адреса необходимых функций посредством GetProcAddress . Это позволит нам в дальнейшем включить эту функцию в программу, которая должна выполняться в том числе и на Windows 9x/Me, где PSAPI.DLL отстутствует. При реализации других способов перечисления процессов мы поступаем таким же образом.

Функция EnumProcesses не позволяет узнать, сколько места нужно для того, чтобы принять весь массив идентификаторов. Поэтому мы вызываем ее в цикле, увеличивая размер буфера, до тех пор, пока размер возвращенного массива не будет меньше размера буфера.

Поскольку мы хотим помимо идентификаторов процессов получить и имена процессов, мы должны проделать дополнительную работу. Для каждого процесса мы сначала получаем его описатель (handle) c помощью функции OpenProcess и затем используем функцию ЕnumProcessModules , которая возвращает список модулей, загруженных в адресное пространство процесса. Первым модулем в списке всегда является модуль, соответсвующий EXE-файлу программы. Наконец, мы вызываем функцию GetModuleFileNameEx (которая также является частью PSAPI), чтобы получить путь к EXE-файлу по описателю модуля. Мы используем имя EXE-файла без пути в качестве имени процесса.

Oбратите внимание на специальную обработку для двух процессов. Мы вынуждены обрабатывать отдельно процесс бездействия системы (Idle) с идентификатором 0, и системный процесс (System), который имеет идентификатор 2 на Windows NT 4 и 8 — на Windows 2000/XP, потому что OpenProcess не позволяет открыть описатель для этих процессов, возвращая код ошибки ERROR_ACCESS_DENIED.

Если вы запустите тестовое приложение, прилагающееся к этой статье, то обнаружите, что для одного из процессов в качестве имени возвращается «(name unavailable)». Запустив Task Manager нетрудно определить, что этим процессом является CSRSS.EXE. Оказывается, система устанавливает такой дескиптор безопасности этому процессу, который не позволяет открыть его с необходимыми нам правами доступа.

С одной стороны, мы могли бы поступить с этим процессом так же, как с процессами Idle и System, однако нет уверенности, что идентификатор этого процесса является постоянным. С другой стороны, проблему можно решить, включив (enable) привилегию SE_DEBUG_NAME. Когда включена эта привилегия, вызывающий поток может открывать процессы с любыми флагами доступа, независимо от того, какой дескриптор безопасности назначен процессу. Поскольку эта привилегия открывет возможности по преодолению системы безопасности Windows NT, ее имеют лишь администраторы компьютера, и мы не стали добавлять код для включения привилегии непосредственно в функцию EnumProcesses_PsApi . Если необходимо, то привилегия может быть включена перед вызовом EnumProcesses_PsApi , и тогда функция вернет имя и для процесса CSRSS.EXE.

Способ 2. Использование ToolHelp32 API

Корпорация Microsoft добавила набор функций под названием ToolHelp API в Windows 3.1, чтобы позволить сторонним разработчикам получить доступ к системной информации, которая ранее была доступна только программистам Microsoft. При создании Windows 95, эти функции перекочевали в новую систему под названием ToolHelp32 API. Операционная система Windows NT c cамого создания содержала средства для получения подобной информации под названием «данные производительности». Интерфейс для доступа к данным производительности был крайне запутанным и неудобным (справедливости ради надо отметить, что начиная с Windows NT 4.0, Microsoft предоставляет библиотеку Performance Data Helper, значительно облегчающую получение данных производительности; мы воспользуемся этой библиотекой при реализации соответствующего метода перечисления процессов). Говорят, команда Windows NT долгое время сопротивлялась включению ToolHelp32 API в систему, тем не менее, начиная с Windows 2000, ToolHelp32 API присутствует и в этой операционной системе.

Используя ToolHelp32 API, мы сначала создаем моментальный снимок (snapshot) списка процессов с помощью функции CreateToolhelp32Snapshot , а затем проходим по списку используя функции Process32First и Process32Next . Структура PROCESSENTRY32 , заполняемая этими функциями, содержит всю необходимую информацию. Ниже приведен код функции EnumProcesses_ToolHelp , реализующей перечисление процессов с помощью ToolHelp32.

Перед вызовом функций Process32First и Process32Next мы должны инициализировать поле dwSize структуры PROCESSENTRY32 таким образом, чтобы оно содержало размер структуры. Функции в свою очередь заносят в это поле количество байтов, записанных в структуру. Мы сравниваем это значение со смещением поля szExeFile в структуре, чтобы определить, было ли заполнено имя процесса.

Способ 3. Использование функции ZwQuerySystemInformation

Несмотря на наличие документированного способа получения списка процессов в Windows NT с помощью данных производительности, Windows NT Task Manager никогда не использовал этот интерфейс. Вместо этого он использовал недокументированную функцию ZwQuerySystemInformation , экспортируемую из NTDLL.DLL, которая позволяет получить доступ к самой разнообразной системной информации и списку процессов в том числе.

Функция ZwQuerySystemInformation имеет следующий прототип [2]:

SystemInformationClass задает тип получаемой информации, нас интересует SystemProcessesAndThreadsInformation (5)
SystemInformation указатель на буфер, принимающий запрошенную информацию
SystemInformationLength задает длину приемного буфера в байтах
ReturnLength указатель на переменную, в которую заносится количество байтов, записанных в выходной буфер

Формат информации о процессах и потоках описывается структурой SYSTEM_PROCESSES , которая содержит почти всю информацию, отображаемую Task Manager. Ниже привeден код функции EnumProcesses_NtApi , реализующей перечисление процессов с использованием функции ZwQuerySystemInformation .

При вызове ZwQuerySystemInformation трудно заранее определить, какой размер выходного буфера будет достаточным, поэтому мы начинам с буфера размером 32K и увеличиваем его по необходимости.

Структура SYSTEM_PROCESSES имеет переменный размер, поле NextEntryDelta указывает смещение к следующей струтктуре в массиве. Наличие этого поля позволяет нам игнорировать различия в размере фиксированной части структуры между Windows NT 4.0 и Windows 2000, где в состав структуры было добавлено поле IoCounters .

Способ 4. Использование cчетчиков производительности

Как уже отмечалось, операционная система Windows NT с самого создания содержала интерфейс для получения разнообразной информации о системе в виде счетчиков производительности. Этот интерфейс является, скажем, далеко не интуитивным. Для получения той или иной информации нужно прочитать из ключа реестра HKEY_PERFORMANCE_DATA значение со специально сформированным именем. В результате возвращается набор глубоко вложенных структур, многие из которых переменного размера, и разбор этих данных требует определенной усидчивости.

Ситуация изменилась в лучшую сторону с появлением в Windows NT 4.0 библиотеки Performance Data Helper (PDH), которая предоставляет более удобный интерфейс к данным производительности. Эта библиотека, однако, не входила в комплект поставки Windows NT 4.0, она распространялась в составе Microsoft Platform SDK. В Windows 2000 PDH.DLL присутствует по умолчанию.

Подробное рассмотрение данных производительности выходит за рамки данной статьи, отметим лишь, что система подсчета производительности в Windows NT определяет понятие объекта , для которого осуществляется подсчет производительности. Примерами объектов являются процессор и жесткий диск. Каждый объект может иметь один или более экземпляров , и для каждого объекта существует свой набор счетчиков производительности . Наша задача состоит в перечислении всех экземпляров объекта с именем «Process» и получении для каждого из них значения счетчика с именем «ID Process». Ниже приведен код функции EnumProcesses_PerfData , которая использует PDH для перечисления процессов.

Мы возвращаем имя экземпляра объекта в качестве имени процесса. Если вы запустите тестовую программу, то увидите, что имена экземпляров соответсвуют именам исполняемых файлов процессов без расширения.

Названия объектов и счетчиков производительности являются локализуемыми. Это значит, что, например, на русской версии Windows NT необходимо использовать «Процесс» и «Идентификатор процесса» вместо «Process» и «ID Process». Для получения локализованных имен объектов и формирования полного пути к интересующему нас счетчику производительности служит вспомогательная функция PerfFormatCounterPath , исходный код которой приведен ниже.

Мы используем функцию PdhLookupPerfNameByIndex , чтобы получить локализованные имена по их индексам. Для стандартных объектов и счетчиков производительности индексы являются постоянными и не зависят от версии операционной системы, поэтому вполне безопасно задать значения индексов непосредственно в коде.

Отметим, что из перечисленных выше методов, этот метод — первый, который позволяет перечислить процессы на другом компьютере. Все что нужно сделать — это указать имя компьютера в поле szMachineName структуры PDH_COUNTER_PATH_ELEMENTS .

Способ 5. Использование Windows Management Instrumentation

Windows Management Instrumentation (WMI) является реализацией Mircrosoft для так называемой технологии Web-Based Enterprise Management (WBEM). WBEM определяет унифицированную архитектуру, которая позволяет получать данные от различных источников, построенных с помощью различных технологий и платформ, и единообразно представлять эти данные. WBEM основана на схеме общей информационной модели (Common Information Model, CIM), которая является индустриальным стандартом, управляемым Distributed Management Task Force (DMTF). WMI поставляется в составе Windows 2000, но также может быть установлен на Windows 95/98/Me и Windows NT 4.0.

Сколько-либо подробное рассмотрение WMI выходит за рамки этой статьи. Ограничимся лишь кодом, который перечисляет процессы с использованием интерфейсов, предоставляемых WMI.

Поскольку WMI основана на технологии COM, это избавило нас от необходимости явно загружать требуемые библиотеки, как это мы делали в предыдущих примерах. Этот же факт требует инициализации библиотеки COM прежде чем будет вызвана функция перечисления процессов. В приложении, созданном с использованием MFC, это можно сделать с помощью функции AfxOleInit , в остальных случаях следует пользоваться функциями CoInitialize или CoInitializeEx .

Кроме того, использование WMI требует инициализации безопасности COM с помощью функции CoInitializeSecurity :

Заметим, что как и метод с использованием счетчиков производительности, этот метод позволяет перечислить процессы на другом компьютере, для чего нужно указать имя компьютера в вызове IWbemLocator::ConnectServer .

Перечисление процессов на другом компьютере в том виде, в котором оно представлено в последних двух примерах, будет работать только если текущий пользователь локального компьютера включен в группу администраторов удаленного компьютера. Приведенные выше примеры не позволяют изменить имя пользователя и пароль, с которыми производится подключение. Чтобы указать альтернативные имя пользователя и пароль, для PDH следует использовать функцию NetUseAdd или WNetAddConnection2 чтобы установить аутентифицированное соединение с ресурсом IPC$ на удаленном компьютере. Для WMI следует использовать стандартные средства COM. Подробное рассмотрение этих механизмов выходит за рамки данной статьи.

Заключение

Таким образом, мы рассмотрели пять различных способов получения списка процессов. Ни один из них не является универсальным, так как существует версия Windows, где этот метод не работает. Приведенная ниже таблица показывает применимость различных методов.

Windows 9x/Me Windows NT 4.0 Windows 2000/XP
Способ 1 Нет Да * Да
Способ 2 Да Нет Да
Способ 3 Нет Да Да
Способ 4 Нет Да * Да
Способ 5 Да * Да * Да
* Требует установки дополнительных компонент.

Используя эту таблицу и приведенные выше функции, несложно написать функцию перечисления процессов, которая будет работать на всех версиях Windows. Например, если мы хотим использовать PSAPI при работе на Windows NT/2000/XP и ToolHelp32 API — на Windows 9x/Me, то функция будет выглядеть следующим образом:

Как проверить список запущенных процессов в Windows?

В статье описывается несколько способов, которые помогут отобразить список запущенных процессов в Windows. Операции производятся в Windows 10, но что-то сработает и в более ранних версиях.
Согласитесь, задача отобразить список запущенных процессов далеко не самая сложная. Однако подходы к её решению не обязательно должны быть стандартными. Информацию по процессам можно представить и в более комфортном виде, чем, например, через…

Диспетчер задач

Чаще всего, кроме этого способа, пользователям больше ничего и не известно. Но, раз уж это так, значит, этого большинству из нас достаточно. Вызывается оный во всех последних версиях Windows просто – достаточно зажать три клавиши быстрого доступа:

Ctrl + Shift + Esc

Вкладка с процессами не изменилась со времён Windows XP:

Однако, если вы на К76, вам Диспетчера мало. Согласен, продолжаем.

Список запущенных процессов из командной строки

В Windows есть встроенная командная утилита tasklist, отображающая список запущенных процессов на указанном компьютере. Как и многие другие в папке System32, tasklist принадлежит к числу административных утилит, которые могут смотреть запущенные процессы на удалённых машинах по сети. Для локального компьютера команда в консоли, запущенной от имени администратора, может, например, принять такой вид:

После этого на Рабочем столе появится текстовый файл:

в котором запущенные на момент исполнения команды будут представлены в удобочитаемом виде. Текстовый вывод не понимает кириллицы, так что я обычно использую специальные текстовые редакторы типа Notepad ++. Но, думаю, что в файле написано, понятно и так:

Или процессы можно представить в табличном формате; если есть Excel, можете просматривать процессы оттуда:

Для удалённого компьютера команда примет вид:

На этом можно было бы и закончить, но я продолжу аналогичным вариантом, откуда вы узнаете…

Как узнать список запущенных процессов из Power Shell

Информация из файла, получаемого аналогичным путём, будет немного более информативнее. Этот вариант доступен владельцам копий Windows 7/10, и командлет на отображение списка на том же Рабочем столе будет таким:

для локальной копии Windows:

  • Handles – число потоков, которые процесс открыл для себя.
  • NPM(K) – размер невыгружаемого пула памяти, использующегося процессом, в килобайтах.
  • PM(K) – размер выгружаемого пула памяти, использующегося процессом, в килобайтах.
  • WS(K) – размер рабочего набора процесса, в килобайтах. Он состоит из страниц памяти, к которым процесс обращался в текущем сеансе.
  • VM(M) – объём оперативной памяти, занимаемой процессом, в мегабайтах (в том числе в pafefile).
  • CPU(s) – время в секундах, затрачиваемое всеми камнями процессора.
  • ID – PID указанного процесса.
  • ProcessName – Имя процесса.
Читайте также:  Как настроить электропитание процессора windows 10
Оцените статью