-
May 24th, 2014, 07:37 PM
#1
Thread Starter
Hyperactive Member
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
-
May 24th, 2014, 08:03 PM
#2
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
-
May 24th, 2014, 09:57 PM
#3
Thread Starter
Hyperactive Member
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?
-
May 24th, 2014, 10:10 PM
#4
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
-
May 24th, 2014, 10:50 PM
#5
Thread Starter
Hyperactive Member
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.
-
May 25th, 2014, 12:21 AM
#6
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
-
May 25th, 2014, 10:47 AM
#7
Thread Starter
Hyperactive Member
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.
-
May 25th, 2014, 11:11 AM
#8
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.
-
May 25th, 2014, 12:22 PM
#9
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
-
May 25th, 2014, 12:27 PM
#10
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.
-
May 25th, 2014, 08:59 PM
#11
Thread Starter
Hyperactive Member
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.
-
May 25th, 2014, 09:35 PM
#12
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
-
May 25th, 2014, 09:50 PM
#13
Thread Starter
Hyperactive Member
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.
-
May 25th, 2014, 10:11 PM
#14
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
-
May 26th, 2014, 03:07 AM
#15
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
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|