dcsimg
Results 1 to 15 of 15

Thread: How to get Process ID from hwnd?

  1. #1

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    How to get Process ID from hwnd?

    I have this code to get the Process ID from the hwnd, but it does not return the Process ID. What am I doing wrong?

    Code:
    Option Explicit
    
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
    ByVal lpFile As String, ByVal lpParameters As String, _
    ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    
    Private Declare Function GetWindowThreadProcessId Lib "user32" _
      (ByVal hwnd As Long, lpdwprocessid As Long) As Long
      
    Const SW_SHOW = 5
    
    Private Sub Command1_Click()
        Dim retVal As Long
        Dim idProc As Long
        Dim lngProcID as Long
        retVal = ShellExecute(Me.hwnd, "open", "notepad.exe", vbNullString, vbNullString, SW_SHOW)
        GetWindowThreadProcessId Me.hwnd, idProc
        lngProcID = idProc
    End Sub

  2. #2
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,346

    Re: How to get Process ID from hwnd?

    Try

    Code:
    Option Explicit
    
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
    ByVal lpFile As String, ByVal lpParameters As String, _
    ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    
    Private Declare Function GetWindowThreadProcessId Lib "user32" _
      (ByVal hwnd As Long, lpdwprocessid As Long) As Long
      
    Const SW_SHOW = 5
    
    Private Sub Form_Load()
        Dim retVal As Long
        Dim idProc As Long
        Dim lngProcID As Long
        retVal = ShellExecute(Me.hwnd, "open", "notepad.exe", vbNullString, vbNullString, SW_SHOW)
        lngProcID = GetWindowThreadProcessId(Me.hwnd, idProc)
       MsgBox (lngProcID)
    End Sub
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  3. #3

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    Re: How to get Process ID from hwnd?

    So I use your code and I get the number 47408. Looking in Task Manager, the PID of notepad.exe is 41132. If I run...

    retVal = Shell "notepad.exe"

    The return value is the PID. How can I get the real PID when using ShellExecute?

  4. #4
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,346

    Re: How to get Process ID from hwnd?

    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  5. #5

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    Re: How to get Process ID from hwnd?

    Yes, that's the exact document I was looking at... it's were I found the GetWindowThreadProcessId function. Errr... VB6 is frustrating! I need to use ShellExcute in order to hide the DOS window because Shell with vbHide doesn't hide the window, but then I need the PID, which seems impossible to get! UGH! Maybe I should just take the time and rewrite the program in VB.net.

  6. #6
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,346

    Re: How to get Process ID from hwnd?

    Try the code in post #8 here.

    Edit:

    If I am not mistaken the PID changes depending on how many instances of a program you have open, etc.
    Last edited by Nightwalker83; May 25th, 2014 at 12:48 AM. Reason: Adding more!
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  7. #7

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    Re: How to get Process ID from hwnd?

    When you open a program like notepad, that process has the same PID until it is closed. Of course if you launch notepad 50 times, there will be 50 different PIDs, but each one of those windows keeps it's own PID until it is closed.

    The code in the link might work if I search for the title of the window. It just seems strange that there is not an easy way to grab the PID when you know the hwnd. It does seem possible in VB.net. My main goal is to hide the window of the program I launch, but I need to know the PID. Maybe I can keep using Shell and somehow position the window to location outside of the screen. If not, I think I will reprogram my application in VB.net, unless someone knows a simple way to get the PID after launching a 3rd party program with ShellExecute.

  8. #8
    Hyperactive Member
    Join Date
    Oct 2013
    Posts
    389

    Re: How to get Process ID from hwnd?

    Why not just use FindWindow + GetWindowThreadProcessId after you shellexecuted what-ever you wanted ?

    if all you want to do is hide it:
    Code:
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
    ByVal lpFile As String, ByVal lpParameters As String, _
    ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    
    Private Sub Form_Load()
        Call ShellExecute(Me.hwnd, "open", "notepad.exe", vbNullString, vbNullString, vbHide)
    End Sub
    Last edited by stum; May 25th, 2014 at 11:23 AM.

  9. #9
    PowerPoster
    Join Date
    Aug 2011
    Location
    B.C., Canada
    Posts
    2,887

    Re: How to get Process ID from hwnd?

    Since your not telling us what you need to do exactly, you change idea every post.
    With this you will get hWnd from pID and hide it with it's hwnd.
    Whatever you need to do you will be able to, since you got the hwnd (that works will most APIs) and also got the pID to activate.
    Only problem is I don't think you can activate a hidden window. So again not sure what the hell you need to do.

    With this code (and beyond) you should be able to go to the moon with your "DosProgram".
    Code:
    Option Explicit
    
    Private Const GW_HWNDNEXT = 2
    Private Const GWL_STYLE = -16
    
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
    Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare Function ShowWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal ndx As Long, ByVal newValue As Long) As Long
    Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
    Private PID As Long
    
    ' Return the window handle for an instance handle.
    Private Function InstanceToWnd(ByVal target_pid As Long) As Long
    Dim test_hwnd As Long
    Dim test_pid As Long
    Dim test_thread_id As Long
    
        ' Get the first window handle.
        test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
    
        ' Loop until we find the target or we run out
        ' of windows.
        Do While test_hwnd <> 0
            ' See if this window has a parent. If not,
            ' it is a top-level window.
            If GetParent(test_hwnd) = 0 Then
                ' This is a top-level window. See if
                ' it has the target instance handle.
                test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
    
                If test_pid = target_pid Then
                    ' This is the target.
                    InstanceToWnd = test_hwnd
                    Exit Do
                End If
            End If
    
            ' Examine the next window.
            test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
        Loop
    End Function
    
    
    Private Sub Command1_Click()
    Dim lhWnd As Long
    
    PID = Shell("C:\Windows\Notepad.exe", vbMaximized)
    lhWnd = InstanceToWnd(PID)
    SetParent lhWnd, Me.hWnd
    ShowWindow lhWnd, vbHide ' // hide the window
    SetWindowLong lhWnd, GWL_STYLE, vbHide  ' // set the style
    ShowWindow lhWnd, vbNormal ' // show the window for the new style to come into effect
    ShowWindow lhWnd, vbHide ' // hide the window so we can't see it
    
    End Sub

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,720

    Re: How to get Process ID from hwnd?

    What are you really trying to do?

    Starting an invisible instance of Notepad seems absurd, so I'm guess that's meant as some sort of example.

    SendKeys in any form is clunky and unreliable because anything else might activate and take focus any time.

    There is no "DOS." "DOS" is long gone.

    There is nothing magical about ShellExecute, which is just a very, very fat wrapper around CreateProcess and several other API calls and registry probes. Somebody gave you some very poor advice in your other thread.


    So I ask once more: What are you really trying to do?

    If we knew that, we might have more useful suggestions.

  11. #11

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    Re: How to get Process ID from hwnd?

    What I am doing is launching a VPN program that happens to be a command line program. Then I need to send username and password. I tried using SendMessage and PostMessage and every other method that was suggested and nothing worked 100% of the time. Everything that I tried was completely unreliable until I found a function someone had written called apiSendKeys. It has worked flawlessly every time!

    The command I launch looks like this...

    pID = Shell("openvpn.exe --config ""C:\Program Files (x86)\SSL VPN Client\config\" & Text1.Text & "@filter.domain.org\" & Text1.Text & "@filter.domain.org.ovpn"" --ca ""C:\Program Files (x86)\SSL VPN Client\config\" & Text1.Text & "@filter.domain.org\filter.domain.org.ca.crt"" --cert ""C:\Program Files (x86)\SSL VPN Client\config\" & Text1.Text & "@filter.domain.org\filter.domain.org.user.crt"" --key ""C:\Program Files (x86)\SSL VPN Client\config\" & Text1.Text & "@filter.domain.org\filter.domain.org.user.key""", vbMinimizedFocus)

    From there I grab the window using "AppActivate pID", I send the text using apiSendKeys and it works every time. The only problem now is that the command line window use to close, but the program has changed and now it stays open and needs to stay open. I just want the window to be hidden. Of course I tried using vbHide, but the window still shows. The program works perfectly, I just want the command line window to be hidden. I wish there was a way to do it without rewriting the code because it works flawlessly now and I don't want to spend days fiddling to make it work. I'll try Max187Boucher's code, but if I run the program with Shell using vbHide, it doesn't hide the window. I read in a thread that vbHide doesn't hide a command line window.

  12. #12
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,346

    Re: How to get Process ID from hwnd?

    I don't understand why you can't use any of the example I posted or link to above? As you confirm each instance of a program is suppose to have different PID. Also, just because you start "Notepad" the first day and it has a PID of "41132" doesn't mean the PID of "Notepad" is going to be the same the next day or the day after that, it depends on the system and how many processes are already running to what PID a instance of a program it happens to receive.
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  13. #13

    Thread Starter
    Hyperactive Member BrianPaul's Avatar
    Join Date
    Aug 2007
    Posts
    294

    Re: How to get Process ID from hwnd?

    Of course the PID is going to be different every time you launch the program. The reason I couldn't use the code you posted above is because it doesn't seem to really give the process id and hence doesn't work. When I tested it, the PID was 47408, but your code said it was 41132. Of course if I ran it again, your program might say it's 38105 when it's really 42216. That code doesn't give the PID as you see in Task Manager (maybe thread PID is different?). If your run the command...

    pID = Shell "notepad.exe"

    It returns the actual PID as you would see in Task Manger. Try it yourself with the code you posted... launch notepad, output the PID and see if it matches what you see in Task Manager.

  14. #14
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,346

    Re: How to get Process ID from hwnd?

    This seems to work correctly.

    Code:
       Private Type STARTUPINFO
          cb As Long
          lpReserved As String
          lpDesktop As String
          lpTitle As String
          dwX As Long
          dwY As Long
          dwXSize As Long
          dwYSize As Long
          dwXCountChars As Long
          dwYCountChars As Long
          dwFillAttribute As Long
          dwFlags As Long
          wShowWindow As Integer
          cbReserved2 As Integer
          lpReserved2 As Long
          hStdInput As Long
          hStdOutput As Long
          hStdError As Long
       End Type
    
       Private Type PROCESS_INFORMATION
          hProcess As Long
          hThread As Long
          dwProcessID As Long
          dwThreadID As Long
       End Type
    
       Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
          hHandle As Long, ByVal dwMilliseconds As Long) As Long
    
       Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
          lpApplicationName As String, ByVal lpCommandLine As String, ByVal _
          lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
          ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
          ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
          lpStartupInfo As STARTUPINFO, lpProcessInformation As _
          PROCESS_INFORMATION) As Long
    
       Private Declare Function CloseHandle Lib "kernel32" _
          (ByVal hObject As Long) As Long
    
       Private Declare Function GetExitCodeProcess Lib "kernel32" _
          (ByVal hProcess As Long, lpExitCode As Long) As Long
    
       Private Const NORMAL_PRIORITY_CLASS = &H20&
       Private Const INFINITE = -1&
       Dim APP As String
    
       Public Function ExecCmd(cmdline$)
          Dim proc As PROCESS_INFORMATION
          Dim start As STARTUPINFO
    
          ' Initialize the STARTUPINFO structure:
          start.cb = Len(start)
    
          ' Start the shelled application:
          RET& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _
             NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)
    '           Me.Print proc.hThread
    '           Me.Print proc.hProcess
    '           Me.Print proc.dwThreadID
               Me.Print proc.dwProcessID
          ' Wait for the shelled application to finish:
             RET& = WaitForSingleObject(proc.hProcess, INFINITE)
             Call GetExitCodeProcess(proc.hProcess, RET&)
             Call CloseHandle(proc.hThread)
             Call CloseHandle(proc.hProcess)
             ExecCmd = RET&
       End Function
    
       Sub Form_Click()
          APP = "notepad.exe"
          ExecCmd (APP)
       End Sub
    Edit:

    Check the number on the form after you closes notepad to confirm whether or not the number matches the PID displayed in Task Manager.
    Last edited by Nightwalker83; May 25th, 2014 at 10:16 PM. Reason: Adding more!
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  15. #15
    Software Carpenter dee-u's Avatar
    Join Date
    Feb 2005
    Location
    Candon City, Ilocos Sur, Phils.
    Posts
    11,010

    Re: How to get Process ID from hwnd?

    The program here returns the same PID as that of the Task Manager, perhaps you can lift ideas there

    http://www.vb-helper.com/howto_pid_to_hwnd.html
    Regards,


    As a gesture of gratitude please consider rating helpful posts. c",)

    Some stuffs: Mouse Hotkey | Compress file using SQL Server! | WPF - Rounded Combobox | WPF - Notify Icon and Balloon | NetVerser - a WPF chatting system

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width