Jump to content
Sign in to follow this  
superbem

How to get the Windowl handle by PID

Recommended Posts

superbem

I can get the PID easily:

$activeWin=ProcessExists("sample.exe")

but this don't work:

$activeWin = WinGetHandle($activeWin)

And I need it for this:

DllCall("User32.dll", "int", "PostMessageA", "hwnd", $activeWin, "int", "0x0012", "int", "", "int", "")

This is a quit program, and I need to exit the sample.exe with this wm_quit command, a kill process wont do.

Thanks

Share this post


Link to post
Share on other sites
Wooltown

You could use WinList() !

Share this post


Link to post
Share on other sites
superbem

And how to use it for this?

This don't work:

$aWin=ProcessExists("sample.exe")
$activeWin = WinList($aWin)
DllCall("User32.dll", "int", "PostMessageA", "hwnd", $activeWin, "int", $WM_QUIT, "int", "", "int", "")

And this don't work too:

$activeWin = WinList("sample.exe")
DllCall("User32.dll", "int", "PostMessageA", "hwnd", $activeWin, "int", $WM_QUIT, "int", "", "int", "")
Edited by superbem

Share this post


Link to post
Share on other sites
Wooltown

According to help file

; $array[0][0] = Number of windows returned

; $array[1][0] = 1st window title

; $array[1][1] = 1st window handle (HWND)

$Process = WinList("sample.exe")

If $Process[0][0] <> 0 Then; - We found the window
    $Process[1][1] - This is the handle for the Window
    DllCall("User32.dll", "int", "PostMessageA", "hwnd", $Process[1][1], "int", $WM_QUIT, "int", "", "int", "")
EndIf

Share this post


Link to post
Share on other sites
Chefito

Of the help Autoit:

ProcessClose

--------------------------------------------------------------------------------

Terminates a named process.

ProcessClose ( "process" [, flag] )

If it is a windows:

WinClose

--------------------------------------------------------------------------------

Closes a window.

WinClose ( "title" [, "text"] )

OR

WinKill

--------------------------------------------------------------------------------

Forces a window to close.

WinKill ( "title" [, "text"] )

Saludos :)

Share this post


Link to post
Share on other sites
ProgAndy

There was a Function hre in the Forum, but I don't find it anymore.

Some time ago, I created on, too: http://www.autoit.de/index.php?page=Thread...42581#post42581

CODE
#include<Array.au3>

$a = ProcessList('firefox.EXE')

For $i = 1 To UBound($a) - 1

_ArrayDisplay(ProcessGetWindows($a[$i][1]))

Next

; Description: Lists all Windows of a process

; Return Value: Returns an Array like WinList, if error, @error is set to 1, but Still an empty Array is returned.

;Author: AspirinJunkie, modified by Prog@ndy

Func ProcessGetWindows($PId)

$PId = ProcessExists($PId)

If $PId = 0 Then

SetError(1)

Else

Local $WinList = WinList()

Local $WindowTitle[1][2]

Local $x = 0

For $i = 1 To $WinList[0][0]

If WinGetProcess($WinList[$i][1], "") = $PId And $WinList[$i][0] <> ""Then

ReDim $WindowTitle[$x+1][2]

$WindowTitle[$x][0] = $WinList[$i][0]

$WindowTitle[$x][1] = $WinList[$i][1]

$x += 1

EndIf

Next

Return $WindowTitle

EndIf

EndFunc ;==>ProcessGetWindow

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
Monamo

I can get the PID easily:

$activeWin=ProcessExists("sample.exe")

but this don't work:

$activeWin = WinGetHandle($activeWin)

And I need it for this:

DllCall("User32.dll", "int", "PostMessageA", "hwnd", $activeWin, "int", "0x0012", "int", "", "int", "")

This is a quit program, and I need to exit the sample.exe with this wm_quit command, a kill process wont do.

Thanks

Here ya go:

CODE

#include <Constants.au3>

$hWnd = ""

$iPID = ProcessExists("sample.exe")

$aWinList = WinList()

For $i = 1 To $aWinList[0][0]

If WinGetProcess($aWinList[$i][0]) = $iPID Then

$hWnd = $aWinList[$i][1]

ExitLoop

EndIf

Next

If $hWnd <> "" Then

DllCall("User32.dll", "int", "PostMessageA", "hwnd", $hWnd, "int", $WM_QUIT, "int", "", "int", "")

Else

MsgBox(64,"Not Found", "No matching process found.")

EndIf


- MoChr(77)& Chr(97)& Chr(100)& Chr(101)& Chr(32)& Chr(121)& Chr(97)& Chr(32)& Chr(108)& Chr(111)& Chr(111)& Chr(107)-------I've told you 100,000 times not to exaggerate!-------Don't make me hit you with my cigarette hand...-------My scripts:Random Episode Selector, Keyboard MouseMover, CopyPath v2.1, SmartRename for XP,Window Tracer[sup]New![/sup]

Share this post


Link to post
Share on other sites
SmOke_N

Guess I'm lost here with the PostMessage api call, what's wrong with WinClose or even WinKill if necessary?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
superbem

Thanks to all, but still don't have the answer to How to retrieve the handle of a process by is process name or pid.

or in other way, is it possible to send a wm message to a process simply using pid, as ahk?

PostMessage,  0x12,,,,ahk_pid %pid%

Share this post


Link to post
Share on other sites
ProgAndy

Didn't you see my post? I posted a Function to List all Windows with Names and Handles of one Process :)

(http://www.autoitscript.com/forum/index.php?s=&showtopic=71612&view=findpost&p=523874)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
ProgAndy

This function lists all Windows, including the hidden ones. If your Exe has no Window, It doesn't have a Window-Handle, either.

Why don't you just try my example and put your Exe-Name in. Then you can see all Windows The Exe has. :)

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
superbem

I have tried your function, and the sample exe doesnt appear.

Isn't there a way to post a message to a process that isn't a window?

Share this post


Link to post
Share on other sites
ProgAndy

What??? The ArrayDisplay-Window you get is TOTALLY empty when you do this:?

CODE
#include<Array.au3>

$a = ProcessList('sample.exe')

For $i = 1 To UBound($a) - 1

$Return = ProcessGetWindows($a[$i][1])

_ArrayDisplay($Return)

Next

; Description: Lists all Windows of a process

; Return Value: Returns an Array like WinList, if error, @error is set to 1, but Still an empty Array is returned.

;Author: AspirinJunkie, modified by Prog@ndy

Func ProcessGetWindows($PId)

$PId = ProcessExists($PId)

If $PId = 0 Then

SetError(1)

Else

Local $WinList = WinList()

Local $WindowTitle[1][2]

Local $x = 0

For $i = 1 To $WinList[0][0]

If WinGetProcess($WinList[$i][1], "") = $PId And $WinList[$i][0] <> ""Then

ReDim $WindowTitle[$x+1][2]

$WindowTitle[$x][0] = $WinList[$i][0]

$WindowTitle[$x][1] = $WinList[$i][1]

$x += 1

EndIf

Next

Return $WindowTitle

EndIf

EndFunc ;==>ProcessGetWindow

It's claer, that the String "sample.exe" doesn't show up in the List, because A WINDOW DOESN'T NEED TO HAVE THE PROCESSNAME AS TITLE

Isn't there any String like 0xAB3D15F24 in the Window?

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
superbem

You're right, thanks!

here is the ProcessQuit() I was after:

Func ProcessGetWindows($PId)
$PId = ProcessExists($PId)
If $PId = 0 Then
SetError(1)
Else
Local $WinList = WinList()
Local $WindowTitle[1][2]
Local $x = 0
For $i = 1 To $WinList[0][0]
If WinGetProcess($WinList[$i][1], "") = $PId And $WinList[$i][0] <> ""Then
ReDim $WindowTitle[$x+1][2]
$WindowTitle[$x][0] = $WinList[$i][0]
$WindowTitle[$x][1] = $WinList[$i][1]
$x += 1
EndIf
Next
Return $WindowTitle
EndIf
EndFunc

Func ProcessQuit($filename)
$Return=0
$a = ProcessList($filename)
For $i = 1 To UBound($a) - 1
$Return = ProcessGetWindows($a[$i][1])
Next
If($Return==0) Then
Return
EndIf
DllCall("User32.dll", "int", "PostMessageA", "hwnd", $Return[0][1], "int", $WM_QUIT, "int", "", "int", "")
EndFunc

usage:

ProcessQuit("sample.exe")

cheers

Edited by superbem

Share this post


Link to post
Share on other sites
superbem

ProcessQuit() like ProcessClose()?

Nop, processclose is similar to terminate a process and I don't want that, the processquit sends a message to quit, it have some diferent means.

Share this post


Link to post
Share on other sites
YOUF

$WM_QUIT :variable used without being declared.

ProcessQuit("dog.exe")

Func ProcessGetWindows($PId)

$PId = ProcessExists($PId)

If $PId = 0 Then

SetError(1)

Else

Local $WinList = WinList()

Local $WindowTitle[1][2]

Local $x = 0

For $i = 1 To $WinList[0][0]

If WinGetProcess($WinList[$i][1], "") = $PId And $WinList[$i][0] <> ""Then

ReDim $WindowTitle[$x+1][2]

$WindowTitle[$x][0] = $WinList[$i][0]

$WindowTitle[$x][1] = $WinList[$i][1]

$x += 1

EndIf

Next

Return $WindowTitle

EndIf

EndFunc

Func ProcessQuit($filename)

$Return=0

$a = ProcessList($filename)

For $i = 1 To UBound($a) - 1

$Return = ProcessGetWindows($a[$i][1])

Next

If($Return==0) Then

Return

EndIf

DllCall("User32.dll", "int", "PostMessageA", "hwnd", $Return[0][1], "int", $WM_QUIT, "int", "", "int", "")

EndFunc

Share this post


Link to post
Share on other sites
ratus69

just add Global Const $WM_QUIT = 18 and this fine piece will work smoothly

I use it to close the systemtray of utorrent so utorrent won't recheck gigas of downloaded torrents when I restart it

thanks for this thread, it was really helpfull to close a process sending a close order when WInclose doesn't work

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.