joseLB Posted December 26, 2008 Share Posted December 26, 2008 Today I started a program with RUN(...). The only parameter ($cmdline) was the program name. After that, normally you need to wait for the program to "start", or, in my case, I needed to call _ScreenCapture_CaptureWnd. Title, class, hwnd, etc. where not avaiable.Most of the control functions need a title, a class, or hwnd, etc. Most functions DO NOT use PID. I solved my problem with a script from BRETT and monoceres that converts PID to hWND, at PID -> Window Handle (hWND) conversionMy suggestion: RUN, RUNWAIT, etc., to have one more last parameter. -> Default=0, returns just PID as today. -> Value=1, returns an array with some parameters (including hwind), something like WinList(), but including PID also. -> Value=2, returns an array, something like WinGetPos(), but including PID and hwnd. -> .....RegardsJose Link to comment Share on other sites More sharing options...
ProgAndy Posted December 26, 2008 Share Posted December 26, 2008 (edited) It is not possible to get the windows from a PID. Possibly there is a way, but it is a secret of M$. It is possible to get the PID from a window, so the workaround is, to loop all windows and check which process they belong to. Edited December 26, 2008 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 Link to comment Share on other sites More sharing options...
joseLB Posted December 26, 2008 Author Share Posted December 26, 2008 It is not possible to get the windows from a PID. Possibly there is a way, but it is a secret of M$. It is possible to get the PID from a window, so the workaround is, to loop all windows and check which process they belong to.That's Brett solution, as follows. But is hard to believe that If I'm starting a process, I can't have all information about it, as for example WinList and other does... Func _GetHwndFromPID($PID) $hWnd = 0 $stPID = DllStructCreate("int") Do $winlist2 = WinList() For $i = 1 To $winlist2[0][0] If $winlist2[$i][0] <> "" Then DllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $winlist2[$i][1], "ptr", DllStructGetPtr($stPID)) If DllStructGetData($stPID, 1) = $PID Then $hWnd = $winlist2[$i][1] ExitLoop EndIf EndIf Next Sleep(100) Until $hWnd <> 0 Return $hWnd EndFunc;==>_GetHwndFromPID Link to comment Share on other sites More sharing options...
ProgAndy Posted December 26, 2008 Share Posted December 26, 2008 If you don't believe it, just search MSDN and google. I found no other solution or API function to do that. Windows stores those things, but you have to use the known APIs.WinList / EnumWindows lists all windowsWinGetProcess / GetWindowThreadProcessId fetches PID from HWNDRun / CreateProcess just returns PID there is no Window Handle, since a process can have none, one or multiple windows. *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 Link to comment Share on other sites More sharing options...
jvanegmond Posted December 26, 2008 Share Posted December 26, 2008 That's Brett solution, as follows. But is hard to believe that If I'm starting a process, I can't have all information about it, as for example WinList and other does...That's actually a common mistake. But in reality, what you just described would be a "do all" function. A "do all" function would be bad for everyone, because it would be limiting them. You can't take functionality away from premade functions, you can only extend functionality. So instead, we split up the functions in a way so that you may use them to build your own "do all" function exactly as how you would like it.Knowing this, you could write your own function that would:1) Start the process using function parameters2) Find all the window handles that are being opened for that process and gather some other information you would like3) Put all that information in an array and use it as the return handle to your function.Once you've done that, you'll also understand some of the more technically challenging things about writing such a function. Such as, once a process is created it doesn't always instantly create it's Windows.Good luck. github.com/jvanegmond Link to comment Share on other sites More sharing options...
Valik Posted December 26, 2008 Share Posted December 26, 2008 Manadar said it best. It's not going to happen natively. That's why we made a scripting language, not a language where every function can do every single thing every single user wants right out of the box. Link to comment Share on other sites More sharing options...
cppman Posted December 26, 2008 Share Posted December 26, 2008 I'm not really sure how practical this is (or even how "workable" it is). You can setup a windows shell hook. In your hook procedure, check for "HSHELL_WINDOWCREATED", then call GetWindowThreadProcessId to check if the Process ID of the window is the same as the process ID returned by Run.There was a callback UDF floating around the forum a while ago - it may come in handy if you use this method.http://msdn.microsoft.com/en-us/library/ms644990.aspx - SetWindowsHookExhttp://msdn.microsoft.com/en-us/library/ms644991(VS.85).aspx - ShellProchttp://msdn.microsoft.com/en-us/library/ms633522(VS.85).aspx - GetWindowThreadProcessId Miva OS Project Link to comment Share on other sites More sharing options...
Valik Posted December 26, 2008 Share Posted December 26, 2008 Shell hooks require being inside a DLL. Link to comment Share on other sites More sharing options...
cppman Posted December 26, 2008 Share Posted December 26, 2008 (edited) Shell hooks require being inside a DLL.Ah... I forgot about that. Edited December 26, 2008 by cppman Miva OS Project Link to comment Share on other sites More sharing options...
jvanegmond Posted December 26, 2008 Share Posted December 26, 2008 Shell hooks require being inside a DLL.This is to ensure that they can be accessed from any other process, or what? github.com/jvanegmond Link to comment Share on other sites More sharing options...
Valik Posted December 26, 2008 Share Posted December 26, 2008 WH_SHELL can be set either as thread or global. Setting it on a out-of-process thread or on all threads (global) requires a DLL so it can be loaded into the address space of those processes. Setting it on an in-process thread seems rather useless as the only notifications you will get will revolve around you but not other windows (I haven't tested this). Link to comment Share on other sites More sharing options...
Bee Posted January 26, 2009 Share Posted January 26, 2009 Today I started a program with RUN(...). The only parameter ($cmdline) was the program name. After that, normally you need to wait for the program to "start", or, in my case, I needed to call _ScreenCapture_CaptureWnd. Title, class, hwnd, etc. where not avaiable. Most of the control functions need a title, a class, or hwnd, etc. Most functions DO NOT use PID. I solved my problem with a script from BRETT and monoceres that converts PID to hWND, at PID -> Window Handle (hWND) conversion My suggestion: RUN, RUNWAIT, etc., to have one more last parameter. -> Default=0, returns just PID as today. -> Value=1, returns an array with some parameters (including hwind), something like WinList(), but including PID also. -> Value=2, returns an array, something like WinGetPos(), but including PID and hwnd. -> ..... Regards JoseHere my two cents: CODE#include <array.au3> $iPid = Run("notepad.exe") Sleep(100) ; allow notepad to create window $aArray = _WinGetInfoByProcess($iPid, 1) _ArrayDisplay($aArray, "by Pid, only visible windows") $aArray = _WinGetInfoByProcess("notepad.exe", -1) _ArrayDisplay($aArray, "by Name, all windows") $aArray = _WinGetInfoByProcess("notepad.exe", 0) _ArrayDisplay($aArray, "by Name, only invisible windows") $aArray = _WinGetInfoByProcess("notepad.exe", 1) _ArrayDisplay($aArray, "by Name, only visible windows") $hHandle = _WinGetInfoByProcess("notepad.exe") ; default is $nShow = 2 ControlSend($hHandle, "", "", "{alt}{right 2}{down 2}{enter}") Sleep(300 * ControlSend("[active]", "", "", "{tab 2}{BS}72{enter}")) ; allow window to change ControlSend("[active]", "", "", "{enter} Hello World.") Func _WinGetInfoByProcess($vProcess, $nShow = 2) ; ;=============================================================================== ; ; Function Name: _WinGetInfoByProcess ; Description:: Get Window Handle of Process ; Parameter(s): $vProcess = Processname(e.g. "Notepad.exe") or Processnumber(e.g. 4711 ) ; $nShow = -1 "All (Visble or not)" ; $nShow = 0 "Not Visible Only" ; $nShow = 1 "Visible Only" ; $nShow = 2 "Return handle of newest window " (Default) ; Requirement(s): none ; Return Value(s): ; @extended = returns number of entries in the array ; @error = 0 AND $nShow = 2 (default) returns handle of newest window ; @error = 0 returns array with processinfos ; n = 1 to @extended ; Array[n][0] shows windows title. ; Array[n][1] shows windows handle. ; Array[n][2] shows windows Pid. ; @error = 1 Process not found. ; @error = 2 Window not found. ; Author(s): Bee ; inspired by Smoke_N's script _WinGetHandleByPID() ; but to handle more than one process with the same name ; and to return handle of newest window ($nShow = 2). ; tested versions: Autoit 3.3.0.0 ; ;=============================================================================== ; If Not ProcessExists($vProcess) Then Return SetError(1, 0, 0) ; no matching process Local $iWinList, $aWinList = WinList() Local $iResult, $aResult[uBound($aWinList)][3] Local $iProcessList, $aProcessList = ProcessList($vProcess) If $aProcessList[0][0] = 0 Then Local $aProcessList[2][2] = [[1, 0],["", $vProcess]] For $iWinList = 1 To $aWinList[0][0] For $iProcessList = 1 To $aProcessList[0][0] If WinGetProcess($aWinList[$iWinList][1]) = $aProcessList[$iProcessList][1] Then If $nShow > -1 And Not $nShow = (2 = BitAND(WinGetState($aWinList[$iWinList][1]), 2)) Then ContinueLoop $iResult += 1 $aResult[$iResult][0] = $aWinList[$iWinList][0] $aResult[$iResult][1] = $aWinList[$iWinList][1] $aResult[$iResult][2] = $aProcessList[$iProcessList][1] EndIf Next Next If $iResult = 0 Then Return SetError(2, 0, 0) ; no window found ReDim $aResult[$iResult + 1][3] $aResult[0][0] = $iResult If $nShow = 2 Then Return SetError(0, $iResult, $aResult[1][1]) Return SetError(0, $iResult, $aResult) EndFunc ;==>_WinGetInfoByProcessJust execute it and see what happens. Link to comment Share on other sites More sharing options...
Developers Jos Posted January 26, 2009 Developers Share Posted January 26, 2009 Hey tiny .... back again ??? Cya Jos SciTE4AutoIt3 Full installer Download page  - Beta files    Read before posting   How to post scriptsource   Forum etiquette Forum Rules  Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Valik Posted January 26, 2009 Share Posted January 26, 2009 (edited) TinyBoy, you aren't affecting Jos. I'm the one cleaning up your mess at the moment but don't get your hopes up that you are really affecting me all that much. It's rather amusing at this point, actually. So thank you for being a form of entertainment.However, to answer your question, yes, I am satisfied even if Jos isn't. You've admitted you were going to attack us and now we have logs proving that you did indeed attack us. I'm sure your ISP will be quite interested in seeing these new logs where you DoS our issue tracker. I bet they would be interested in that PM you sent to the staff, too. It should go along quite nicely with the previous information we already sent them. Feel free to continue your actions. The more evidence of your behavior we get the better.Oh, and if you wish to speak to Jos or any of us for that matter then use #771. Have fun. Toodles. Edited January 26, 2009 by Valik Removed a word that shouldn't have been there. Link to comment Share on other sites More sharing options...
TinyMan Posted January 27, 2009 Share Posted January 27, 2009 Oh, and if you wish to speak to Jos or any of us for that matter then use #771. Have fun. Toodles.Yeah, I'll have fun.But speaking by #771 is not possible, since you 'banned' the IP's of my old proxy 'Kabel Deutschland' and no access to TRAC was possible. Error 403So I changed my proxy and used another userid to communicate in this topic.I have enough proxies around the world. ;-)Like this one.My real ISP is difficult to expose. And again: Please reinstate banned users: Tinyboy and JellyFish666ThanksTinyboy Link to comment Share on other sites More sharing options...
Valik Posted January 27, 2009 Share Posted January 27, 2009 Yeah, I'll have fun.But speaking by #771 is not possible, since you 'banned' the IP's of my old proxy 'Kabel Deutschland' and no access to TRAC was possible. Error 403So I changed my proxy and used another userid to communicate in this topic.I have enough proxies around the world. ;-)Like this one.My real ISP is difficult to expose. And again: Please reinstate banned users: Tinyboy and JellyFish666ThanksTinyboy So let me summarize this and you can confirm if I'm correct.For no personal reason at all you decide to "teach" me a lesson and attack our issue tracker.You are banned for your behavior in attacking our issue tracker (as well as banned for having multiple accounts)Unhappy at being banned you now try to use your attacks as leverage to get us to cave in to your demands.You stop the attacks for some reason.You come onto the forum again and are promptly banned.In retaliation you go back to threatening us and demanding accounts be unbanned.So does that about sum up your behavior? May I ask you a serious question? What is wrong with you. You go out of your way to attack somebody and then threaten to attack them further when they retaliate. Does that not strike you as incredibly stupid on your part? You can't honestly expect us to actually give in to your demands. So what is it you expect? Do you enjoy making me take 15 seconds to run a script to clean up after you? Do you enjoy causing me to learn useful things to combat you? It seems like whatever goal you have in mind you are having an inverse effect. You aren't really affecting anybody you are aiming at unless you're aiming at innocent people. I can't tell you the number of legitimate tickets that have been blocked because of measures put in place to keep you out. Is that your goal? To stop legitimate users of this site from being able to use the site? You really aren't affecting the staff myself or Jos, the two people you have issue with.Know this: Your demands will never be met. You can stop asking now. We will never unban those accounts. You will never be knowingly allowed on this website again. Neither will be the idiot that was banned at your expense. Right now there is a reason I'm not banning you but that reason will soon expire and you will once again have your account banned. All future accounts will be banned. All tickets created by you will be automatically deleted. You may continue to attack this community all you want but know that you hurt yourself and you hurt a lot of innocent people far more than you ever hurt us. You don't hurt us at all, actually. You hurt the community. You make their life difficult. Is that your goal? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now