Шрифт:
Рис. 13.2. Взаимосвязь процесса и потоков Win32
Взаимодействие с процессами в рамках платформы .NET
Хотя процессы и потоки сами по себе не являются чем-то новым, способы взаимодействия с этими примитивами в рамках платформы .NET существенно изменены (к лучшему). Чтобы успешно пройти путь к пониманию приемов построения компоновочных блоков с поддержкой множества потоков (см. главу 14), мы начнем с обсуждения возможностей взаимодействия с процессами на основе использования библиотек базовых классов .NET.
Пространство имен System.Diagnostics определяет ряд типов, позволяющих программное взаимодействие с процессами, а также типов, связанных с диагностикой системы (например, с журналом регистрации системных событий и счетчиками производительности). В этой главе мы рассмотрим только те связанные с процессами типы, которые определены в табл. 13.1.
Таблица 13.1. Избранные члены пространства имен System.Diagnostics
Типы System.Diagnostics для поддержки процессов | Описание |
---|---|
Process | Класс Process обеспечивает доступ к локальным и удаленным процессам, а также позволяет программно запускать и останавливать процессы |
ProcessModule | Этот тип представляет модуль (*.dll или *.exe), загруженный в рамках конкретного процесса. При этом тип ProcessModule может представлять любой модуль – модуль COM, модуль .NET или традиционный двоичный файл C |
ProcessModuleCollection | Предлагает строго типизованную коллекцию объектов ProcessModule |
ProcessStartlnfo | Указывает множество значений, используемых при запуске процесса с помощью метода Process.Start |
ProcessThread | Представляет поток в рамках данного процесса. Тип ProcessThread используется для диагностики множества потоков процесса, а не для того, чтобы порождать новые потоки выполнения в рамках данного процесса |
ProcessThreadCollection | Предлагает строго типизованную коллекцию объектов PrосessThread |
Тип System.Diagnostics.Process позволяет проанализировать процессы, выполняемые на данной машине (локальной или удаленной). Класс Process предлагает также члены, которые позволяют запускать и останавливать процессы программными средствами, устанавливать уровни приоритета и получать список активных потоков и/или загруженных модулей, выполняемых в рамках данного процесса. В табл. 13.2 предлагается список некоторых (но не всех) членов System.Diagnostics.Process.
Таблица 13.2. Избранные члены типа Process
Член | Описание |
---|---|
ExitCode | Свойство, содержащее значение, которое указывается процессом при завершении его работы. Для получения этого значения необходимо обработать событие Exited (при асинхронном уведомлении) или вызвать метод WaitForExit (при синхронном уведомлении) |
ExitTime | Свойство, содержащее штамп времени, соответствующий прекращению работы процесса (и представленный типом DateTime) |
Handle | Свойство, возвращающее дескриптор, назначенный процессу операционной системой |
HandleCount | Свойство, возвращающее число дескрипторов, открытых процессом |
Id | Свойство, содержащее идентификатор процесса (PID) для данного процесса |
MachineName | Свойство, содержащее имя компьютера, на котором выполняется данный процесс |
MainModule | Свойство, получающее тип ProcessModule, который представляет главный модуль данного процесса |
MainWindowTitle MainWindowHandle | Свойство MainWindowTitle получает заголовок главного окна процесса (если процесс не имеет главного окна, будет возвращена пустая строка). Свойство MainWindowHandle получает дескриптор (представленный типом System.IntPtr) соответствующего окна. Если процесс не имеет главного окна, типу IntPtr присваивается значение System.IntPtr.Zero |
Modules | Свойство, обеспечивающее доступ к строго типизованной коллекции ProcessModuleCollection, представляющей множество модулей (*.dll или *.exe), загруженных в рамках текущего процесса |
PriorityBoostEnabled | Это свойство указывает, должна ли операционная система временно ускорять выполнение процесса, когда его главное окно получает фокус ввода |
PriorityClass | Свойство, позволяющее прочитать или изменить данные базового приоритета соответствующего процесса |
ProcessName | Свойство, содержащее имя процесса (которое, как вы можете догадаться, соответствует имени приложения) |
Responding | Значение этого свойства указывает, должен ли пользовательский интерфейс процесса реагировать на действия пользователя |
StartTime | Свойство с информацией о времени, соответствующем старту данного процесса (эта информация представлена типом DateTime) |
Threads | Свойство, получающее набор потоков, выполняющихся в рамках данного процесса (представляется массивом типов ProcessThread) |
CloseMainWindow | Метод, завершающий процесс с пользовательским интерфейсом путем отправки соответствующего сообщения о закрытии главного окна |
GetCurrentProcess | Статический метод, возвращающий тип Process, используемый для представления процесса, активного в настоящий момент |
GetProcesses | Статический метод, возвращающий массив компонентов Process, выполняющихся на данной машине |
Kill | Метод, немедленно прекращающий выполнение соответствующего процесса |
Start | Метод, начинающий выполнение процесса |
Список выполняемых процессов
Чтобы привести пример обработки типов Process, предположим, что у нас есть консольное приложение C# ProcessManipulator, которое определяет следующий вспомогательный статический метод.
Обратите внимание на то, что статический метод Process.GetProcesses возвращает массив типов Process, представляющих процессы, запущенные на выполнение на целевой машине (используемая здесь точка обозначает локальный компьютер).
После получения массива типов Process можно использовать любой из членов, приведенных в табл. 13.2. Здесь просто отображается значение PID и имя каждого из процессов. В предположении о том, что вы обновили метод Main для вызова ListAllRunningProcesses, в результате выполнения соответствующей программы вы должны увидеть нечто подобное показанному на рис. 13.3.
Рис. 13.3. Перечень запущенных процессов
Чтение данных конкретного процесса
В дополнение к полному списку всех запущенных на данной машине процессов, статический метод Process.GetProcessById позволяет прочитать данные отдельного процесса по его значению PID. Если запросить доступ к процессу по несуществующему значению PID, будет сгенерировано исключение ArgumentException. Так, чтобы получить объект Process, представленный значением PID, равным 987, можно написать следующее.