For a little while I have been wresting with some Windows Api code which enumerates all of the processes, enumerates all the modules and then for the first module handle (conventionally the exe name) return the image (file) name. Except it's broken, something to do with mixing 32 and 64 bit processes. Arggghhh!
So why not for some WMI code? Here is some below, and is nice and short. I'm guess WMI has been developed as part of the Powershell initiative and so is probably the future. I think I will reach for WMI first hand in future.
Option Explicit
Sub TestGetProcessIds()
    Dim dicProcessIds As Scripting.Dictionary
    Set dicProcessIds = GetProcessIds("excel.exe")
    Debug.Print dicProcessIds.Keys()(0)
End Sub
'**********************************************************************************
'* GetProcessIds uses WMI's Win32_Process instead of
'* EnumProcesses, EnumProcessModules and GetModuleFileNameExA to match exe name
'**********************************************************************************
Function GetProcessIds(ByVal sImageName As String) As Scripting.Dictionary
    Dim dicProcessIds As Scripting.Dictionary
    Set dicProcessIds = New Scripting.Dictionary
    Dim objWMIService As Object
    Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
    Dim colItems As Object
    Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process" & _
               " WHERE Name = '" & sImageName & "'", , 48)
    Dim objItem As Object
    For Each objItem In colItems
        If Not dicProcessIds.Exists(objItem.ProcessId) Then 
            dicProcessIds.Add objItem.ProcessId, 0
        End If
    Next
    
    Set GetProcessIds = dicProcessIds
End Function
No comments:
Post a Comment