viper941
viper941

Reputation: 156

Determine Process ID with VBA

Situation - I have a macro where I need to send keystrokes to two Firefox windows in order. Unfortunately both windows have the same title. To handle this I have activated the window, sent my keystrokes, then used F6 to load the URL of the second window and then send the keystrokes then use F6 to return it to the original page.

The issue is that loading the webpages is unreliable. Page load speeds vary so much that using a wait command is not consistent or reliable to ensure the keystroke makes it to the second window.

Question - I've read a scattering of posts that mentioned that app activate will work with Process ID's. Since each window would have its own PID that would be an ideal way to handle 2 windows with the same title. I am unable to find information specifically how to determine the PID of each window with a given name.

Upvotes: 3

Views: 11460

Answers (1)

JNevill
JNevill

Reputation: 50064

You can use something like the following. You'll have to tinker about with the different info available in the Win32_Process class to figure out which window is which. It's also important to keep in mind that one window could mean many processes.

Public Sub getPID()        
    Dim objServices As Object, objProcessSet As Object, Process As Object

    Set objServices = GetObject("winmgmts:\\.\root\CIMV2")
    Set objProcessSet = objServices.ExecQuery("SELECT ProcessID, name FROM Win32_Process WHERE name = ""firefox.exe""", , 48)

    'you may find more than one processid depending on your search/program
    For Each Process In objProcessSet
       Debug.Print Process.ProcessID, Process.Name
    Next

    Set objProcessSet = Nothing       

End Sub

Since you'll probably want to explore the options with WMI a bit, you may want to add a Tools>>References to the Microsoft WMI library so you don't have to deal with Dim bla as Object. Then you can add breakpoints and see what's going on in the Locals pane.

After adding the reference:

Public Sub getDetailsByAppName()

    Dim objProcessSet As WbemScripting.SWbemObjectSet
    Dim objProcess As WbemScripting.SWbemObject
    Dim objServices As WbemScripting.SWbemServices
    Dim objLocator As WbemScripting.SWbemLocator

    'set up wmi for local computer querying
    Set objLocator = New WbemScripting.SWbemLocator
    Set objServices = objLocator.ConnectServer(".") 'local

    'Get all the gory details for a name of a running application
    Set objProcessSet = objServices.ExecQuery("SELECT * FROM Win32_Process WHERE name = ""firefox.exe""", , 48)

    RecordCount = 1
    'Loop through each process returned
    For Each objProcess In objProcessSet
        'Loop through each property/field
        For Each Field In objProcess.Properties_
            Debug.Print RecordCount, Field.Name, Field.Value
        Next
        RecordCount = RecordCount + 1
    Next

    Set objProcessSet = Nothing
    Set objServices = Nothing
    Set objLocator = Nothing


End Sub

That will print out every property of every process found for the name 'firefox.exe'.

Upvotes: 5

Related Questions