Изучение процессов
35C# --- Сборки .NET --- Изучение процессов
Помимо полного списка всех выполняющихся на конкретной машине процессов, статический метод Process.GetProcessById() позволяет получать информацию и по конкретному объекту Process за счет указания ассоциируемого с ним идентификатора (PID). В случае запроса несуществующего PID генерируется исключение ArgumentException.
Набор потоков представляется в виде строго типизованной коллекции ProcessThreadCollection, в которой содержится определенное количество отдельных объектов ProcessThread. Свойство Threads в System.Diagnostics.Process предоставляет доступ к классу ProcessThreadCollection, некоторые наиболее интересные члены которого перечислены ниже:
- CurrentPriority
Позволяет получить информацию о текущем приоритете потока
- Id
Позволяет получить уникальный идентификатор потока
- IdealProcessor
Позволяет указать предпочитаемый процессор для выполнения данного потока
- PriorityLevel
Позволяет получить или задать уровень приоритета потока
- ProcessorAffinity
Позволяет указать процессоры, на которых может выполняться соответствующий поток
- StartAddress
Позволяет узнать, по какому адресу в памяти операционная система вызывала функцию, приведшую к запуску данного потока
- StartTime
Позволяет узнать, когда операционная система запустила поток
- ThreadState
Позволяет узнать текущее состояние данного потока
- TotalProcessorTime
Позволяет узнать, сколько всего времени данный поток использовал процессор
- WaitReason
Позволяет узнать причину, по которой поток находится в состоянии ожидания
Прежде чем двигаться дальше, необходимо четко уяснить, что тип ProcessThread не является сущностью, применяемой для создания, приостановки и уничтожения потоков в .NET. Он скорее представляет собой средство, позволяющее получать диагностическую информацию по активным потокам Windows внутри выполняющегося процесса.
Теперь давайте посмотрим, как реализовать проход по загруженным модулям, которые обслуживаются в рамках конкретного процесса. При обсуждении процессов модуль — это общий термин, используемый для описания заданной сборки *.dll (или *.ехе), которая обслуживается в определенном процессе. При получении доступа к ProcessModuleCollection через свойство Process.Modules можно извлечь список всех модулей, которые обслуживаются внутри процесса: .NET, СОМ и традиционных основанных на С библиотек.
И, наконец, последними членами класса System.Diagnostics.Process, которые осталось рассмотреть, являются методы Start() и Kill(). Эти методы позволяют, соответственно, программно запускать и завершать процесс. Метод Start() может принимать тип System.Diagnostics.ProcessStartInfо и предоставлять дополнительные фрагменты информации относительно запуска определенного процесса.
Давайте рассмотрим пример глобального изучения процессов:
using System;
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Console.WriteLine("*** ПРОЦЕССЫ ***\n");
string comm = Command();
UseMyCommand(comm);
// Используем рекурсию для вызова новых команд
if (comm != "X")
Main();
}
static string Command()
{
Console.WriteLine("Какую информацию нужно получить? \n"+
" 1 - Список всех процессов\n 2 - Выбрать процесс по PID\n"+
" 3 - Информация о потоках\n 4 - Информация о подключаемых модулях\n"+
" 5 - Запуск процесса\n 6 - Останов процесса\n X - выход\n");
Console.Write("Введите команду: ");
string comm = Console.ReadLine();
return comm;
}
static void UseMyCommand(string str)
{
switch (str)
{
case "X":
break;
case "1":
AllInfoProcess();
break;
case "2":
ProcInMyPid();
break;
case "3":
Threads();
break;
case "4":
InfoByModuleProc();
break;
case "5":
StartProcess();
break;
case "6":
StopProcess();
break;
default:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Команда не распознана!");
Console.ForegroundColor = ConsoleColor.Gray;
break;
}
Console.WriteLine();
}
static void AllInfoProcess()
{
var myProcess = from proc in Process.GetProcesses(".")
orderby proc.Id select proc;
Console.WriteLine("\n*** Текущие процессы ***\n");
foreach (var p in myProcess)
Console.WriteLine("-> PID: {0}\tName: {1}",p.Id,p.ProcessName);
}
static void ProcInMyPid()
{
Console.Write("Введите PID-идентификатор: ");
string pid = Console.ReadLine();
Process myProc = null;
try
{
int i = int.Parse(pid);
myProc = Process.GetProcessById(i);
Console.WriteLine("\n-> PID: {0}\tName: {1}\n",myProc.Id,myProc.ProcessName);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void Threads()
{
Console.Write("Введите PID-идентификатор: ");
string pid = Console.ReadLine();
Process myProc = null;
try
{
int i = int.Parse(pid);
myProc = Process.GetProcessById(i);
// Получаем коллекцию потоков процесса
ProcessThreadCollection threads = myProc.Threads;
Console.WriteLine("Потоки процесса {0}:\n", myProc.ProcessName);
foreach (ProcessThread pt in threads)
Console.WriteLine("-> Thread ID: {0}\tВремя: {1}\tПриоритет: {2}"
, pt.Id, pt.StartTime.ToShortTimeString(), pt.PriorityLevel);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine();
}
}
static void InfoByModuleProc()
{
Console.Write("Введите PID-идентификатор: ");
string pid = Console.ReadLine();
Process myProc = null;
try
{
int i = int.Parse(pid);
myProc = Process.GetProcessById(i);
Console.WriteLine("Подключаемые модули процесса {0}:\n", myProc.ProcessName);
// Получаем коллекцию модулей
ProcessModuleCollection mods = myProc.Modules;
foreach (ProcessModule pm in mods)
Console.WriteLine("-> Имя модуля: "+pm.ModuleName);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine();
}
}
static void StartProcess()
{
Process myProc = null;
// Запустить сайт professorweb.ru на машине пользователя
try
{
// Будет работать только для пользавателей у которых установлен браузер Google Chrome
// Чтобы запустить IE, нужно запустить процесс IExplore.exe
myProc = Process.Start("chrome.exe", "www.professorweb.ru");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static void StopProcess()
{
Console.Write("Введите PID-идентификатор процесса, который нужно остановить: ");
string pid = Console.ReadLine();
Process myProc = null;
try
{
int i = int.Parse(pid);
myProc = Process.GetProcessById(i);
myProc.Kill();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Данное приложение является многофункциональным и позволяет просмотреть все текущие процессы на машине пользователя, найти процесс по PID-идентификатору, получить информацию о потоках и подключаемых модулях процесса, а также запустить или остановить процесс (в качестве примера запуска процесса приведен запуск браузера Google Chrome и передача ему URL professorweb.ru).