Programming Windows Services with Microsoft Visual Basic 2008 : WMI System Monitoring

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
Although WMI is great for gathering information, it can also be a very powerful monitoring and debugging tool. In this section we will use WMI to monitor the processes on our system and then use WMI to shut down an application that we define as behaving poorly. Because we don’t want to negatively affect our system at the moment, we will simulate this sitation by using NotePad.exe.

Updating the Configuration File

We need to be able to store the process or processes that we want to monitor for. Listing 1 shows the updated configuration file with the process element added.

Listing 1. Process monitoring elements.

We can implement the process element in several ways, depending on the complexity that we want to create. You can choose from the following options:

  • Create a master <Processes> element with subelements called <Process>. You’ll need to modify the <ThreadFunc> method of your Tutorials class so that it can parse all the processes that have been entered. Then you’ll have to update the WMIWorkerOptions class to store an array of process names.

  • Create a single element (as I’ve done in the previous example). I called my element process, and then placed the specific process name that I want to monitor.

  • Create a single element but place a delimited list of processes to monitor.

Any of these options will work, though some require more work than others. For demonstration purposes, I have taken what I consider the simplest approach and created a single element with a single process name, Notepad.

WMI Win32_Process Usage

In this section we will use the Win32_Process class (shown in Listing 2) from WMI to monitor for any application named Notepad.exe. When we find an instance of Notepad, we will use WMI to shut it down.

Listing 2. Win32_Process WMI class implemented in the .NET Framework in C#.
class Win32_Process : CIM_Process
  string Caption;
  string CommandLine;
  string CreationClassName;
  datetime CreationDate;
  string CSCreationClassName;
  string CSName;
  string Description;
  string ExecutablePath;
  uint16 ExecutionState;
  string Handle;
  uint32 HandleCount;
  datetime InstallDate;
  uint64 KernelModeTime;
  uint32 MaximumWorkingSetSize;
  uint32 MinimumWorkingSetSize;
  string Name;
  string OSCreationClassName;
  string OSName;
  uint64 OtherOperationCount;
  uint64 OtherTransferCount;
  uint32 PageFaults;
  uint32 PageFileUsage;
  uint32 ParentProcessId;
  uint32 PeakPageFileUsage;
  uint64 PeakVirtualSize;
  uint32 PeakWorkingSetSize;
  uint32 Priority;
  uint64 PrivatePageCount;
  uint32 ProcessId;
  uint32 QuotaNonPagedPoolUsage;
  uint32 QuotaPagedPoolUsage;
  uint32 QuotaPeakNonPagedPoolUsage;
  uint32 QuotaPeakPagedPoolUsage;
  uint64 ReadOperationCount;
  uint64 ReadTransferCount;
  uint32 SessionId;
  string Status;
  datetime TerminationDate;
  uint32 ThreadCount;
  uint64 UserModeTime;
  uint64 VirtualSize;
  string WindowsVersion;
  uint64 WorkingSetSize;
  uint64 WriteOperationCount;
  uint64 WriteTransferCount;


We will not use all of the class properties available to us. System administrators can use many things to monitor servers based on process performance: threads, handles, memory, virtual memory, CPU usage, and more. A well-written service can monitor a nearly unlimited number of processes per computer while tracking usage over time so that you can determine whether an application is causing a problem.

Although we will gather several pieces of information, we will only use the Name property to determine whether we should shut down the application. This demonstration is not intended to teach you how to design a monitor, but instead to give you an idea of what you can do within a service. When we find an application that matches our <Processes> element, we will shut down the application. We need to make several changes to support this functionality.

Updating the WMIWorkerOptions Class

We need to update the WMIWorkerOptions to store the new process element value that we created. Listing 3 shows the code required to store this information.

Listing 3. WMIWorkerOptions class process update.
Private m_Process As String

Public Property Process() As String
    Return m_Process
  End Get
  Set(ByVal value As String)
    m_Process = value
  End Set
End Property

I added a Process property that we will use to determine the process that we want to monitor for.

Updating the <Tutorials.ThreadFunc> Method

We need to read in the new value from our configuration.xml file and use our WMIWorkerOptions class to store it. We will update the <ThreadFunc> method, as shown in Listing 4.

Listing 4. <ThreadFunc> method update to read the process element.
    children = tmpOptions.SelectSingleNode("Query")
    WWOptions.Query = children.Value

    children = tmpOptions.SelectSingleNode("Server")
    WWOptions.Server = children.Value

    children = tmpOptions.SelectSingleNode("WMIRoot")
    WWOptions.WMIRoot = children.Value

    children = tmpOptions.SelectSingleNode("Process")
							WWOptions.Process = children.Value

    Dim tmpWW As New WMI(m_ThreadAction, WWOptions)
  Catch ex As Exception
    WriteLogEvent(ex.ToString(), CONFIG_READ_ERROR, EventLogEntryType.Error,
  End Try
Loop While (tmpOptions.MoveToNext)


The bolded code in Listing 4 will now use the new process property to store the name of the process—in our case, Notepad.exe—that we want to monitor for. Now that we have our process name we need to update our worker threads to query the processes and then shut down any Notepad.exe instances.

Updating the <Query> Configuration Value

Aside from adding in the appropriate process element, we also need to update our <Query> element to reflect the new dynamic WMI query. Listing 5 shows the update.

Listing 5. New WMI <Query> element value.
<Query>Select * from Win32_Process Where Name = 'Notepad.exe'</Query>

The new <Query> element value will allow us to simplify the resources required to perform the work that we want to do. Because we only care about the Win32_Process class—and more specifically, the Notepad.exe process—we will use the following query only to validate against our desired process. If you want to use this same query for another process, just change the process name from Notepad.exe to whatever you want to search for.

Updating the <WMI.ProcessWMIRequest> Method

We need to modify the <ProcessWMIRequest> method to reflect our required change to shut down any process called Notepad.exe. Listing 6 shows the modifications.

Listing 6. Updated <ProcessWMIRequest> method.
Private Sub ProcessWMIRequest()
  While Not m_ThreadAction.StopThread
    If Not m_ThreadAction.Pause Then
            'Now process the file
            Connect(m_WMIWorkerOptions.Server, m_WMIWorkerOptions.WMIRoot)
            Dim pMOC As ManagementObjectCollection
            pMOC = Query(m_WMIWorkerOptions.Query)
            If Not pMOC Is Nothing Then
                Dim Name As String = Nothing
                Dim ProcessId As String = Nothing
                Dim pMO As ManagementObject
                For Each pMO In pMOC
							ReadProperty(pMO, "Name", Name)
							ReadProperty(pMO, "ProcessId", ProcessId)
							Catch ex As Exception
							Exit For
							End Try
							'Lets Log This Information
							Dim pszOut As String
							'terminate the process
							If Name.Trim = "Notepad.exe" Then
							pMO.InvokeMethod("Terminate", Nothing)
							End If
							pszOut = "Shut down of process Name: " + Name.Trim + vbCrLf
							+ "Process ID: " + ProcessId
                    WriteLogEvent(pszOut, WMI_INFO,
        EventLogEntryType.Information, "Tutorials")
                WriteLogEvent("Thread WMI query Error - " + GetError(),
        WMI_ERROR, EventLogEntryType.Error, "Tutorials")
            End If
        Catch tab As ThreadAbortException
            'Clean up the thread here
            WriteLogEvent("Thread Function Abort Error - " + Now.ToString,
         WMI_ERROR, EventLogEntryType.Error, "Tutorials")
        Catch ex As Exception
            WriteLogEvent("Thread Function Error - " + Now.ToString, WMI_ERROR,
         EventLogEntryType.Error, "Tutorials")
        End Try
    End If

    If Not m_ThreadAction.StopThread Then
    End If
  End While
End Sub


The bolded code shows that we have modified the code to read the Name and ProcessId properties. In reality, because we only queried processes named Notepad.exe, we don’t really need to read the Name property, but it is always better to be safe and validate a process before you terminate it.

After we validate that we are looking at an instance of our queried process, Notepad.exe, we invoke the Terminate method of the WMI Win32_Process class to shut down the process. The last thing we do is write an event into the Application log to show that we accomplished our goal.

Service Function Validation

To ensure that the service is working properly, configure and install the service to monitor for required processes. For each process, add a new entry in the configuration file. Even if the process is on the same computer, you must add one entry per process. For each process that your service finds, you should see the process disappear and then an event appear in the Application log.

You will notice that if a process requires user interaction, such as saving the current file in Notepad, you may be requested to do so before the process shuts down.

Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
- Messages forwarded by Outlook rule go nowhere
- Create and Deploy Windows 7 Image
- How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
- Creating and using an unencrypted cookie in ASP.NET
- Directories
- Poor Performance on Sharepoint 2010 Server
- SBS 2008 ~ The e-mail alias already exists...
- Public to Private IP - DNS Changes
- Send Email from Winform application
- How to create a .mdb file from ms sql server database.......
programming4us programming4us