Are you curious to know what processes are running on your computer? You may be surprised to discover exactly what programs are running and how many run when you boot up. Just a few minutes ago I had 68 processes running. By using VBA to access WMI, I gathered an abundance of information on those processes. There was so much information the Visual Basic Editor Immediate Window could not display it all, so I saved it to a text file.
In our last article we showed how we can get Win32_OperatingSystem Class information by using VBA to access the power of WMI (Windows Management Instrumentation). The the Win32_OperatingSystem Class only has one “instance” on my computer, but there are always a number of instances of processes on a running computer. We can get that information using VBA and WMI but we need to use different code.
In order to get the information on each process running on our computer we need to access each instance in the Win32_Process class. The procedure below shows how to loop through each instance and list all the Property Names and Values of the instance.
This procedure has two arguments we must pass to it. First we pass the Name of the WMI class, Win32_Process. The next argument is the full path and name of the text file to which we want to save the data. For example, the procedure can be run by using Call SaveWMIClassInstancesData(“Win32_Process”, “C:\Win32_ProcessProperties.txt”). Using these arguments gives the code flexibility and allows us to use the same code for other classes. Why write six or seven procedures when you only need to write just one?
Sub SaveWMIClassInstancesData(strClassName As String, strTextFilePath As String)
Dim objWMIServices As Object
Dim colInstances As Object
Dim objInstance As Object
Dim colProperties As Object
Dim objProperty As Object
Dim fso As Object
Dim fsoFile As Object
Dim strComputer As String
Dim strNameSpace As String
Dim intCount As Long
' There may be too much text for the immediate window
' so create a text file and save the data
Set fso = CreateObject("Scripting.FileSystemObject")
' Create an instance of the text file
Set fsoFile = fso.CreateTextFile(strTextFilePath)
strComputer = "."
strNameSpace = "\root\cimv2"
Set objWMIServices = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\" & _
strComputer & strNameSpace)
' Instantiate the Collection of Instances
Set colInstances = objWMIServices.ExecQuery( _
"SELECT * FROM " & strClassName, , 48)
fsoFile.WriteLine "Properties of " & strClassName & " Class Instances "
' Loop through each Instance
intCount = 0
For Each objInstance In colInstances
intCount = intCount + 1
' Get the Properties in the instance
Set colProperties = objInstance.Properties_
' Write some information to the text file
fsoFile.WriteLine vbNewLine
fsoFile.WriteLine "---------------------------------------"
fsoFile.WriteLine " Instance Number: " & intCount
fsoFile.WriteLine "---------------------------------------"
' Write the Property names and values to the text file
For Each objProperty In colProperties
fsoFile.WriteLine objProperty.Name & ": " & objProperty.Value
Next objProperty
Next objInstance
fsoFile.Close
' Release Memory
Set fso = Nothing
Set fsoFile = Nothing
Set objProperty = Nothing
Set colProperties = Nothing
Set objInstance = Nothing
Set colInstances = Nothing
Set objWMIServices = Nothing
End Sub
Below is a sample of the data that was returned about Notepad.
—————————————
Instance Number: 67
—————————————
Caption: notepad.exe
CommandLine: “C:\WINDOWS\system32\notepad.exe”
CreationClassName: Win32_Process
CreationDate: 20090604134043.578125-240
CSCreationClassName: Win32_ComputerSystem
CSName: ACER-HO
Description: notepad.exe
ExecutablePath: C:\WINDOWS\system32\notepad.exe
ExecutionState:
Handle: 5640
HandleCount: 34
InstallDate:
KernelModeTime: 468750
MaximumWorkingSetSize: 1413120
MinimumWorkingSetSize: 204800
Name: notepad.exe
OSCreationClassName: Win32_OperatingSystem
OSName: Microsoft Windows XP Professional
OtherOperationCount: 111
OtherTransferCount: 400
PageFaults: 854
PageFileUsage: 1101824
ParentProcessId: 2248
PeakPageFileUsage: 1101824
PeakVirtualSize: 37982208
PeakWorkingSetSize: 3379200
Priority: 8
PrivatePageCount: 1101824
ProcessId: 5640
QuotaNonPagedPoolUsage: 2400
QuotaPagedPoolUsage: 62108
QuotaPeakNonPagedPoolUsage: 2944
QuotaPeakPagedPoolUsage: 77052
ReadOperationCount: 0
ReadTransferCount: 0
SessionId: 0
Status:
TerminationDate:
ThreadCount: 1
UserModeTime: 468750
VirtualSize: 30683136
WindowsVersion: 5.1.2600
WorkingSetSize: 3379200
WriteOperationCount: 0
WriteTransferCount: 0
The dates that are returned can be converted to a more readable format using the following procedure.
Function WMIDateConvert(dtmDate As String)
WMIDateConvert = CDate(Mid(dtmDate, 5, 2) _
& "/" & Mid(dtmDate, 7, 2) _
& "/" & Left(dtmDate, 4) _
& " " & Mid(dtmDate, 9, 2) _
& ":" & Mid(dtmDate, 11, 2) _
& ":" & Mid(dtmDate, 13, 2))
End Function
Since the processes change each time a program is opened, a text file is a suitable way to save the data. With some other WMI classes you may want to save the data to an Access Table and the SaveWMIClassInstancesData procedure is well suited to be modified for that purpose.
You can learn more about the meaning of the values returned by opening the Win32 Classes web page and scrolling down the list of classes until you find the name of the class you need.
There is also another way to get all of the data available from each instance of a WMI class. We can use the GetObjectText_ Method. This method returns the data in MOF (Managed Object Format). Like the previous procedure, we need to provide the WMI Class Name and the text file name and path as arguments: Call SaveWMIClassMOF(“Win32_Process”, “C:\Win32_ProcessMOFProperties.txt”)
Function SaveWMIClassMOF(strClass As String, Optional strTextFilePath As String) As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim fso As Object
Dim fsoFile As Object
Dim strComputer As String
Dim strNameSpace As String
Dim strMOF As String
Set fso = CreateObject("Scripting.FileSystemObject")
Set fsoFile = fso.CreateTextFile(strTextFilePath)
strComputer = "."
strNameSpace = "\root\cimv2"
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\" & _
strComputer & strNameSpace)
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM " & strClass, , 48)
' This code loops through each instance
' and returns the instance's properties and values
' We build the complete MOF text with the strMOF variable
For Each objItem In colItems
strMOF = strMOF & objItem.GetObjectText_
Next
fsoFile.Write strMOF
fsoFile.Close
Set fso = Nothing
Set fsoFile = Nothing
Set objItem = Nothing
Set colItems = Nothing
Set objWMIService = Nothing
End Function
Below is the MOF data about Notepad.
instance of Win32_Process
{
Caption = “notepad.exe”;
CommandLine = “\”C:\WINDOWS\system32\notepad.exe\” “;
CreationClassName = “Win32_Process”;
CreationDate = “20090604134043.578125-240″;
CSCreationClassName = “Win32_ComputerSystem”;
CSName = “ACER-HO”;
Description = “notepad.exe”;
ExecutablePath = “C:\WINDOWS\system32\notepad.exe”;
Handle = “5640″;
HandleCount = 34;
KernelModeTime = “468750″;
MaximumWorkingSetSize = 1413120;
MinimumWorkingSetSize = 204800;
Name = “notepad.exe”;
OSCreationClassName = “Win32_OperatingSystem”;
OSName = “Microsoft Windows XP Professional”;
OtherOperationCount = “111″;
OtherTransferCount = “400″;
PageFaults = 854;
PageFileUsage = 1101824;
ParentProcessId = 2248;
PeakPageFileUsage = 1101824;
PeakVirtualSize = “37982208″;
PeakWorkingSetSize = 3379200;
Priority = 8;
PrivatePageCount = “1101824″;
ProcessId = 5640;
QuotaNonPagedPoolUsage = 2400;
QuotaPagedPoolUsage = 62108;
QuotaPeakNonPagedPoolUsage = 2944;
QuotaPeakPagedPoolUsage = 77052;
ReadOperationCount = “0″;
ReadTransferCount = “0″;
SessionId = 0;
ThreadCount = 1;
UserModeTime = “468750″;
VirtualSize = “30683136″;
WindowsVersion = “5.1.2600″;
WorkingSetSize = “3379200″;
WriteOperationCount = “0″;
WriteTransferCount = “0″;
};
You may notice when you get MOF data all of the Properties may not be listed. If a Property Value is Null MOF does not return the Property.
The MOF data can be added to an Access table but requires a bit of work. We were able to use string functions to clean up the text and the Split Function to create an array of instances and another array of Properties to add the MOF data to a Table. Modifying the SaveWMIClassInstancesData procedure to add the data to a Table requires much less work and is less likely to produce errors in the data.
MOF is used not only to return data, but also to create new WMI Classes, Properties, and Methods.
Information about WMI Classes is contained in MOF files and describe all of the Properties and Methods of each WMI Class, provide information about Enumerations, and details the the data types that are used. We can access that information using code that returns amended qualifiers as well as the detailed Class information. As before, we use the Class name and a text file path as arguments in calling the Function:
Call SaveWMIClassDescription(“Win32_Service”, “C:\Win32_ServiceMOFDescription.txt”)
Function SaveWMIClassDescription(strClass As String, strTextFilePath As String) As String
Dim objClass As Object
Dim objWMIService As Object
Dim fso As Object
Dim fsoFile As Object
Dim strNameSpace As String
Dim strComputer As String
Dim strMOF As String
Set fso = CreateObject("Scripting.FileSystemObject")
Set fsoFile = fso.CreateTextFile(strTextFilePath)
strComputer = "."
strNameSpace = "\root\cimv2"
'The wbemFlagUseAmendedQualifiers flag is required to get the amended
' Qualifiers and the Class Property and Method description
Const wbemFlagUseAmendedQualifiers = &H20000
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\" & _
strComputer & strNameSpace)
Set objClass = objWMIService.Get(strClass, wbemFlagUseAmendedQualifiers)
strMOF = objClass.GetObjectText_
' Formatting the text makes it much easier to read
' Comment out this block of code to see the raw data
strMOF = Replace(strMOF, ";", ";" & Chr(10))
strMOF = Replace(strMOF, Chr(9), vbNullString)
strMOF = Replace(strMOF, ".\n", "." & Chr(10) & "\n")
strMOF = Replace(strMOF, ":\n", ":" & Chr(10) & "\n")
strMOF = Replace(strMOF, ": \n", ":" & Chr(10) & "\n")
strMOF = Replace(strMOF, "ToSubClass", Chr(10) & "ToSubClass")
SaveWMIClassDescription = strMOF
fsoFile.Write strMOF
fsoFile.Close
Set fsoFile = Nothing
Set fso = Nothing
Set objClass = Nothing
Set objWMIService = Nothing
End Function
We will not take up the space to show a sample returned by this procedure since it will take up a lot of space to display a fairly representative sample.
As you can see VBA can use WMI to provide an abundance of information. We can also read and write to the Registry, read Event Logs, start and stop processes, change hardware settings, install and uninstall software, and much more. We look forward to discovering more about using the capabilities of VBA and WMI in our next article.
Republished from Access Easy Tips [18 clicks].
Read the original version here [32134 clicks].