📜 ⬆️ ⬇️

Work with WMI. Events for processes

It is possible to monitor the process list in different ways, I liked the option using WMI, with which we can handle the process creation, change, delete, etc. event.


We will create our intermediate class for work.

using System;
using System.ComponentModel;
using System.Collections;
using System.Globalization;
using System.Management; // for everything we need to connect the management namespace
')
namespace WMI.Win32
{
public delegate void ProcessEventHandler (Win32_Process proc);

public class ProcessWatcher: ManagementEventWatcher
{
// Process Events
public event ProcessEventHandler ProcessCreated;
public event ProcessEventHandler ProcessDeleted;
public event ProcessEventHandler ProcessModified;

// WMI WQL queries
static readonly string WMI_OPER_EVENT_QUERY = @ "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' "; // request to get a list of all processes
static readonly string WMI_OPER_EVENT_QUERY_WITH_PROC = WMI_OPER_EVENT_QUERY + "and TargetInstance.Name = '{0}' "; // request to get a specific process by the name of the running .exe file

public ProcessWatcher ()
{
Init ( string .Empty);
}

public ProcessWatcher ( string processName)
{
Init (processName);
}
private void Init ( string processName)
{
this .Query.QueryLanguage = "WQL";
if ( string .IsNullOrEmpty (processName))
{
this .Query.QueryString = WMI_OPER_EVENT_QUERY;
}
else
{
this .Query.QueryString =
string .Format (WMI_OPER_EVENT_QUERY_WITH_PROC, processName);
}

this .EventArrived + = new EventArrivedEventHandler (watcher_EventArrived);
}

private void watcher_EventArrived ( object sender, EventArrivedEventArgs e)
{
string eventType = e.NewEvent.ClassPath.ClassName;
Win32_Process proc = new
Win32_Process (e.NewEvent ["TargetInstance"] as ManagementBaseObject);

// determine what event happened
switch (eventType)
{
case "__InstanceCreationEvent" :
if (ProcessCreated! = null )
ProcessCreated (proc);
break ;
case "__InstanceDeletionEvent" :
if (ProcessDeleted! = null )
ProcessDeleted (proc);
break ;
case "__InstanceModificationEvent" :
if (ProcessModified! = null )
ProcessModified (proc); break ;
}
}
}
}

How to use it?

class program
{
static void Main ( string [] args)
{
ProcessWatcher procWatcher = new ProcessWatcher ("notepad.exe"); // we trace actions on notebooks
procWatcher.ProcessCreated + = new ProcessEventHandler (procWatcher_ProcessCreated);
procWatcher.ProcessDeleted + = new ProcessEventHandler (procWatcher_ProcessDeleted);
procWatcher.ProcessModified + = new ProcessEventHandler (procWatcher_ProcessModified);
procWatcher.Start ();
while ( true )
{
procWatcher.WaitForNextEvent (); // wait for the next event
}

procWatcher.Stop (); // yes, logically this code is not reachable, but suddenly we will need to stop following events
}

static void procWatcher_ProcessCreated (Win32_Process process)
{
Console .Write ( "\ nCreated \ n" + process.Name + "" + process.ProcessId);
}

static void procWatcher_ProcessDeleted (Win32_Process proc)
{
Console .Write ( "\ nDeleted \ n" );
}

static void procWatcher_ProcessModified (Win32_Process proc)
{
Console .Write ( "\ nModified \ n" );
}
}


You probably noticed that our ProcessWatcher class uses Win32_Process, which is not in the .NET Framework, to generate it, and generally if you need to work closely with WMI, Microsoft (well done), gave us junk - mgmtclassgen, which will generate a strongly typed class for any WMI tables.
To do this, run the studio console, type mgmtclassgen Win32_Process / n root \ cimv2 / P Win32_Process.cs
We see
Microsoft Management Strongly Typed Class Generator Version
1.1.4322.573
Copyright c Microsoft Corporation 1998-2002. All rights reserved.
Generating Code for WMI Class Win32_Process ...
Code Generated Successfully !!!

And now we are happy we can pick up our finished class from the “C: \ Program Files \ Microsoft Visual Studio 9.0 \ VC” (2008) studio.
If you need to generate a class in different languages, add the / l VB parameter, in this case the vb.net class is ready.
It is worth noting that you just need to replace the class name in the generated file with Win32_Process (wherever it is used), so as not to be confused with System.Diagnostics.Process.

Now it remains to run our program, then run the notepad and voila.

PS I was easily shocked when I saw that in the generated Win32_Process class there was a Russian commentary!

Source: https://habr.com/ru/post/38104/


All Articles