Jump to content

WinWaitReeeallyReady() function?


Recommended Posts

Yay Autoit! So close...

My script captures web browser screens, scrolls, and assembles them in Photoshop. It works great after a clean boot. But most other times it fouls up because one application or another wasn't done painting the screen. e.g. I need to wait for it to finish painting before I do a PrintScreen. I need Photoshop to settle down before I do a Paste (^V). In particular, scrolling Firefox down sometimes takes a lot longer than other times. So pausing for the worst case is iffy.

So I know I could make this work by ( A ) humungous timeouts (the whole script would take half an hour :P ), or ( B ) reboot every time I run it :whistle: . But what I'd really like is a function that was much harder to please than WinWaitActive().

Doesn't anyone else run into this issue? Is there a way already or is this a new feature request?

I can detect when a window is active, but what I'd REALLY like to wait for is: when it's done doing whatever goofoff windoze thing it's doing. Some kind of ping at the windows messaging level, so you can know if it's out of its memory-swapping stupor?

The script feels very brittle. I want it solid.

Link to comment
Share on other sites

Yay Autoit! So close...

My script captures web browser screens, scrolls, and assembles them in Photoshop. It works great after a clean boot. But most other times it fouls up because one application or another wasn't done painting the screen. e.g. I need to wait for it to finish painting before I do a PrintScreen. I need Photoshop to settle down before I do a Paste (^V). In particular, scrolling Firefox down sometimes takes a lot longer than other times. So pausing for the worst case is iffy.

So I know I could make this work by ( A ) humungous timeouts (the whole script would take half an hour :P ), or ( B ) reboot every time I run it :whistle: . But what I'd really like is a function that was much harder to please than WinWaitActive().

Doesn't anyone else run into this issue? Is there a way already or is this a new feature request?

I can detect when a window is active, but what I'd REALLY like to wait for is: when it's done doing whatever goofoff windoze thing it's doing. Some kind of ping at the windows messaging level, so you can know if it's out of its memory-swapping stupor?

The script feels very brittle. I want it solid.

You might be able to use the WaitForInputIdle API call. From MSDN:

This function causes a thread to suspend execution until the specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. Before trying to communicate with

the child process, the parent process can use this function to determine when the child's initialization has been completed. This function can be used at any time, not just during application startup.

This is the AutoIt code to use:

Func _API_WaitForInputIdle($hProcess, $iTimeOut=-1)
  Local $aResult

  $aResult  = DllCall("User32.dll", "dword", "WaitForInputIdle", "hwnd", $hProcess, "dword", $iTimeOut)
  Return $aResult[0]=0)
EndFunc

Where $hProcess is a handle to the process that you are waiting on (you can use something like ProcessList for this) and $iTimeOut is the time (in milliseconds) to wait or -1 to wait until the application is accepting user input. I'm fairly confident this will work for PhotoShop, but IE does things backward most of the time, so you'll have to try it and see.

Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
Share on other sites

This is the AutoIt code to use:

Func _API_WaitForInputIdle($hProcess, $iTimeOut=-1)
  Local $aResult

  $aResult  = DllCall("User32.dll", "dword", "WaitForInputIdle", "hwnd", $hProcess, "dword", $iTimeOut)
  Return $aResult[0]=0)
EndFunc

Where $hProcess is a handle to the process that you are waiting on (you can use something like ProcessList for this) and $iTimeOut is the time (in milliseconds) to wait or -1 to wait until the application is accepting user input. I'm fairly confident this will work for PhotoShop, but IE does things backward most of the time, so you'll have to try it and see.

Thank you, PaulIA! Having trouble getting the process handle.

Error 6 from WaitForInputIdle (returns -1=WAIT_FAILED, then GetLastError returns 6), which means "The handle is invalid." according to MSDN. For the handle, I used the Process ID obtained from ProcessList() (or ProcessExists() or WinGetProcess()). Tried passing it through HWnd(). Also tried the return value from WinGetHandle() (and passing it through HWnd).

Do I need to DllCall("Kernel32.dll", "dword", "OpenProcess" ...) to get a handle?

Would appreciate any further clues on how to get that process handle...

Link to comment
Share on other sites

I tried OpenProcess.

DllCall("Kernel32.dll", "dword", "OpenProcess", "dword", 0x1F0FFF, "int", 0, "dword", $hProcess)

It gave me a handle that WaitForInputIdle liked. But it always returns immediately. Even when Photoshop.exe or firefox.exe are clearly hamstrung.

So was OpenProcess a dumb idea?

Edited by BobSteinVisiBone
Link to comment
Share on other sites

I tried OpenProcess.

DllCall("Kernel32.dll", "dword", "OpenProcess", "dword", 0x1F0FFF, "int", 0, "dword", $hProcess) oÝ÷ Ø`j÷¦y¨ZÙ^¶­Y¨­È­!Ù^)t­Ö¥Á¬¬­ën®{"g«^!/z|!zsá¢Ú,^Åê+~*Þ~^Åæ«yÉ^j¹r©¬¶»§*0jézsë¡Ç¬±§n¸y¯êº^Z+a¢ëe¢"­Ê«r^Ýý²«vÚ-zYGz·¢²0"ëاëhܸ!ü¨¹Ú0Zu§(§*ëhܸ~º&+"v­º·ÚîØ^r^méhÃ*.ßÙe±ç­«b·li¹^¶âÛaxÚ-)ݣʢiÚ.¶Ø^q©e¶!f¢´Z+"zn´e{*.ßÙe±ç­«bµÆ§ßÛ_wmãhµêZw§vyÆ®±è­«'ßÛ_x¬çrzÖ®¶­sb6æ6ÇVFRfÇC´4ÅväæS2fwC° ¤vÆö&Âb33c·E&ö6W72Âb33c·E7F'GWÂb33c¶væ@ £²ÆVæ6æ÷FW@¢b33c·E&ö6W72Ò÷Fu$ô4U55ôädõ$ÔDôâ¢b33c·E7F'GWÒ÷Fu5D%EUädò¥÷Fu6WDFFb33c·E7F'GWÂgV÷Cµ6¦RgV÷C²Â÷FtvWE6¦Rb33c·E7F'GW¥ôô7&VFU&ö6W72gV÷C²gV÷C²ÂgV÷C´3¢b3#µvæF÷w2b3#´æ÷FWBæWRgV÷C²ÂÂÂfÇ6RÂÂÂgV÷C²gV÷C²Â÷FtvWEG"b33c·E7F'GWÂ÷FtvWEG"b33c·E&ö6W72 £²vBf÷"6öÖÖæBFòfæ6¥ôõvDf÷$çWDFÆR÷FtvWDFFb33c·E&ö6W72ÂgV÷C¶&ö6W72gV÷C²¢b33c¶væBÒvävWDæFÆRgV÷CµVçFFÆVBÒæ÷FWBgV÷C²¦bb33c¶væBÒFVâôÆ%õ6÷tW'&÷"gV÷CµVæ&ÆRFòvWBæ÷FWBæFÆRgV÷C² £²6Æ÷6RæFÆW0¥ôô6Æ÷6TæFÆR÷FtvWDFFb33c·E&ö6W72ÂgV÷C¶&ö6W72gV÷C²¥ôô6Æ÷6TæFÆR÷FtvWDFFb33c·E&ö6W72ÂgV÷C¶F&VBgV÷C² ¤gVæ2ôõvDf÷$çWDFÆRb33c¶&ö6W72Âb33c¶FÖT÷WCÒÓ¢Æö6Âb33c¶&W7VÇ@ ¢b33c¶&W7VÇBÒFÆÄ6ÆÂgV÷CµW6W#3"æFÆÂgV÷C²ÂgV÷C¶Gv÷&BgV÷C²ÂgV÷CµvDf÷$çWDFÆRgV÷C²ÂgV÷C¶væBgV÷C²Âb33c¶&ö6W72ÂgV÷C¶Gv÷&BgV÷C²Âb33c¶FÖT÷WB¢&WGW&âb33c¶&W7VÇE³ÓÓ¤VæDgVæ0
Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
Share on other sites

No, it's the handle to the process, not the process ID.

I just briefly look at the Win32_Process's handle property and it gives PID. So just assumed.

Thanks for correction, otherwise I would have wasted OP time. :whistle:

how did you get all this? You are really THE API Extremist!

Edited by Joon
Link to comment
Share on other sites

;
;
_API_CreateProcess("", "C:\Windows\Notepad.exe", 0, 0, False, 0, 0, "", _tagGetPtr($tStartup), _tagGetPtr($tProcess))
;
;
_API_WaitForInputIdle(_tagGetData($tProcess, "hProcess"))
;
;
Ok, I see how to get the handle for a process you created. How does one get the handle of an existing process?

How do I convert a Process ID into a handle (hProcess)?

Link to comment
Share on other sites

Ok, I see how to get the handle for a process you created. How does one get the handle of an existing process?

How do I convert a Process ID into a handle (hProcess)?

AFAIK, if you don't want to use CreateProcess, you will need to use OpenProcess to get the process handle.
Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...