Bluesmaster Posted November 9, 2013 Share Posted November 9, 2013 (edited) Run a process and surpress any windows created by that process that may become visible. Main purpose is to automate gui-applications on a hidden desktop so that the user cannot disturb the process.Its my first attempt to write a UDF so please be patient. Advices, bug reports and recommendations are welcome.. expandcollapse popup#Include <WinAPIEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: ShellExecuteHidden ; ; Description ...: runs a process on another winApi-desktop, so that none of its windows ever get visible, but can be automated by window messages and other technologies. ; The difference to shellExecute( ... , ... , @SW_HIDE ) is, that no just the first, but any windows from the created process will stay totaly isolated from user input and graphics ; ; Syntax ........: ShellExecuteHidden($filepath[, $parameters = "" [, $returnType = 1 [, $waitingOption = -1 ]]]) ; ; Parameters ....: $filepath - the file to run ; ; $returnType = 0 >> returns window handle of toplevel window of the started process ; even if its window is "hidden" (would not be visible on normal desktop) ; = 1 >> returns window handle of toplevel window of the started process ; = 2 >> returns process id (PID) of the started process ; ; ; $waitingOption = -2 >> dont wait (not recommended for window handles, as they need some time to appear even if the program is loading fast) ; = -1 >> wait 1000 milliseconds for windows to "appear" but dont wait for processes to finish (compromise) ; = 0 >> wait for the process to finish or the window to appear ; = <x> >> wait <x> milliseconds for the process to finish or the window to appear (see "$returnType" ) ; ; Return values .: windowHandle or ProcessID ; Author ........: Bluesmaster ; Modified ......: 2013 - 11 - 09 ; Remarks .......: ; Related .......: ShellExecute, _WinAPI_CreateDesktop ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687098(v=vs.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func _shellExecuteHidden( $filepath , $parameters = "" , $returnType = 1 , $waitingOption = -1 ) ; 1 - Create Desktop ;Global Const $GENERIC_ALL = 0x10000000 $hNewDesktop = _WinAPI_CreateDesktop( "ShellExecuteHidden_Desktop" , $GENERIC_ALL ) ; 2 - Start Process $tProcess = DllStructCreate( $tagPROCESS_INFORMATION ) $tStartup = DllStructCreate( $tagSTARTUPINFO ) DllStructSetData( $tStartup , 'Size', DllStructGetSize( $tStartup) ) DllStructSetData( $tStartup , 'Desktop', _WinAPI_CreateString( "ShellExecuteHidden_Desktop" ) ) Local $pid If _WinAPI_CreateProcess( $filepath , $parameters , 0, 0, 0, 0x00000200 , 0, 0, DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) Then $pid = DllStructGetData( $tProcess , 'ProcessID' ) Else Return -1 EndIf ; 3 - Return Process if $returnType = 2 Then if $waitingOption > -1 Then ProcessWaitClose( $pid , $waitingOption ) Return $pid EndIf ; 4 - Return WindowHandle if $waitingOption = -1 Then Sleep( 1000 ) ElseIf $waitingOption > 0 Then Sleep( $waitingOption ) EndIf While True ; keep searching for the window $aWindows = _WinAPI_EnumDesktopWindows( $hNewDesktop , $returnType ) ; $returnType = 0 >> means also list hidden windows if IsArray( $aWindows ) Then for $i = 1 to $aWindows[0][0] ;~ MsgBox( 0 , '' , $curPID & " " & $pid & " " & $hWnd & " " & $aWindows[$i][0] ) $hWnd = $aWindows[$i][0] if $pid = WinGetProcess( $hWnd ) Then ; same process? do ; searching through parent windows ... $hLast = $hWnd ; cache it for not loosing it when desktop is reached $hWnd = _WinAPI_GetParent( $hLast ) Until $hWnd = 0 ; ... until root/ desktop is reached $hWnd = $hLast Return $hWnd ; return the toplevel-window of the process EndIf Next EndIf if $waitingOption = 0 Then ; keep searching for the window until it appears ( in worst case endless ) Sleep( 200 ) Else Return -1 EndIf WEnd EndFunc . Examples: (also included as comment in download file) ; EXAMPLE 1 ( principle ): ; 1 - open a programm with @SW_HIDE ShellExecute( @ComSpec , "/c start notepad.exe" , "" , "" , @SW_HIDE ) WinWaitActive( "[CLASS:Notepad]" ) ControlSend( "[CLASS:Notepad]" , "" , "Edit1" , "As you can see, you cannot prevent an hidden started application " & @LF & "from opening another window that gets visible...") MsgBox( 0 , '' , "I understand. show me the version with appstart on hidden desktop" ) WinKill( "[CLASS:Notepad]" ) ; 2 - do the same routine with "_shellExecuteHidden" $hWinHiddenApp = _shellExecuteHidden( @ComSpec , "/c start notepad.exe" ) ShellExecute( "taskmgr.exe" ) MsgBox( 0 , '' , "...´ok look in your taskmanager now. There should be a new notepad.exe entry but no window is visible." ) ; 3 - close hidden application WinKill( $hWinHiddenApp ) ; EXAMPLE 2 ( interaction ): ; 1 - start hidden application MsgBox( 0 , '' , "Now we start an editor on the hidden desktop and interact with it programmaticly" ) $hWinHiddenApp = _shellExecuteHidden( @SystemDir & "\notepad.exe" ) ; 2 - send to hidden application ControlSend( $hWinHiddenApp , "" , "Edit1" , "di{BS}eb{BS}mk{BS}os{BS}" ) ; 3 - receive information from hidden application MsgBox( 0 , '' , "Text in the editor on hidden desktop: " & @LF & @LF & ControlGetText( $hWinHiddenApp , "" , "Edit1" ) ) ; 4 - close hidden application WinKill( $hWinHiddenApp ) ._shellExecuteHidden.au3winapiex (needed) Edited March 4, 2014 by Bluesmaster KLM and joseLB 2 My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
sSoliduSs Posted November 10, 2013 Share Posted November 10, 2013 (edited) Good work. Maybe you can add this link in your post '?do=embed' frameborder='0' data-embedContent>> . I dont know why, but your demo opens twice Edited November 10, 2013 by sSoliduSs Link to comment Share on other sites More sharing options...
Bluesmaster Posted November 10, 2013 Author Share Posted November 10, 2013 (edited) @sSoliduSs Thank you. Yes Example was included in download file already. Fixed that. Edited November 10, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted November 10, 2013 Share Posted November 10, 2013 I'm not sure WinKill is appropriate to close the newly created desktop. Since it is created with _WinAPI_CreateDesktop then _WinAPI_CloseDesktop would be appropriate.. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Bluesmaster Posted November 10, 2013 Author Share Posted November 10, 2013 I thought about that. But as the main purpose of the fcn is to automate the startet application, the udf would split in 2 parts which decreases the UDFs usability. So deskop just stays open until next reboot. AFAIK it does not comsume relevant ressources or interfere with other processes regards Blues My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
JohnOne Posted November 10, 2013 Share Posted November 10, 2013 So deskop just stays open until next reboot. Just a bit of advice is all. After looking I see you do not even return the new desktop handle. It's entirely up to you of course, but leaving it hanging around is quite lazy, and my advice to anyone who might need such a function is to modify this UDF to return desktop handle, as well as any window handles created in it. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
KLM Posted January 2, 2014 Share Posted January 2, 2014 Thanks K L M ------------------ Real Fakenamovich ------------------ K L M ------------------ Real Fakenamovich ------------------ Link to comment Share on other sites More sharing options...
joseLB Posted January 4, 2014 Share Posted January 4, 2014 Hi Bluesmaster Thanks for sharing. I can be very useful. I have an application that starts a webcam and capture things in it´s screen (PixelSearch). The webcam window is pointed to a specific area and is not to be seen. Now is we need to setup in windows7 a desktop extension where the notebook screen is the main one and another screen is the extension, where the webcam window is. Questions: 1- If I execute the webcam pgm with your udf on a new desktop, probably the coordinate system will be another than main screen . I think that at PixelSearch I need do specify the winhandle, correct? And the coordinates obtained would be relative to webcam application? 2- I suppose that functions like MouseGetPos, mouseMove, etc., would e able to operate just on main screen, correct? Thanks Jose Link to comment Share on other sites More sharing options...
FaridAgl Posted January 4, 2014 Share Posted January 4, 2014 Nice job, it gives me a lots of ideas. You should just try to write a cleaner code, start with closing all handles, for example hThread and hProcess of $tProcess. http://faridaghili.ir Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 5, 2014 Author Share Posted January 5, 2014 @Jose I am not an expert but I think you should not imagine this desktop as a kind of hidden desktop but as an organisation unit for security purposes. Mouse and keyboard ( user-input in general ) can only be processed by the current active desktop. There is also a desktop for the windows logon-screen which can by purpose not be automated. (The screensaver also got one). The next higher organisation unit is the so called "window station" which is used for remote desktop connections for example. This then does also separates the clipboard. You can read further here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681928%28v=vs.85%29.aspx I am also not sure if graphics is processed ( if pixelsearch works ) untit the desktop is active but I would encourage you to share your experiences with us @d4arkon3 I will update it later with cleaner code. I also want to add the oportunity to change the desktop after loading. But I am a bit rare of time at the moment My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
topten Posted January 6, 2014 Share Posted January 6, 2014 @Bluesmaster: Mouse and keyboard ( user-input in general ) can only be processed by the current active desktop. Is there any way to do mouse clicks or sendkey on the created "hidden" desktop without interfering with the main desktop? Thanx in advance!!!!! Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 6, 2014 Author Share Posted January 6, 2014 See example 2 regards My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
topten Posted January 8, 2014 Share Posted January 8, 2014 Thank you very much for your reply. I start my autoit script from a hidden desktop, then it starts IE browser then it tries to send mouse clicks , but unfortunately it doesnt work there. (I checked the result with _IEDocReadHTML($oIE) and also checked with iniwrite)- Btw it really does many things on that hidden desktop- it opens browser, navigates to certain web pages, but when it comes to mouse clicking and sending anything- it doesnt respond. I know, you would advise controlclick, controlsend in this case, but there are many unreachable places overthere. Would it be really more effective to try to create Window station though?- As far as I understood, Window station may allow to interact in an insolated way with the second created station and with desktop on it? Thanx again!!!! Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 8, 2014 Author Share Posted January 8, 2014 I am really rare of time and cannot solve the problem for you. But I can give some small tips. At first ensure that your automations is 100% robust working when it is visible. Use only controlsend and control click! ( if you got no control use x y coordinates on the main window ) Ensure all handles are valid ( consolewrite... ) Ensure window sizes are equal ( wingetpos ... ) Yes you are blind on this desktop and yes this is a big problem But take it as challenge. If you dont understand why something isnt working: Build small test guis ( which you can better get informations from than from internet explorer ). Make experiments... Dont give up and please share your experiences good luck Blues My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
topten Posted January 8, 2014 Share Posted January 8, 2014 Ha! I have missed the fact, that ControlClick can also work with coordinates Anyway, thank you very much for your support and for your nice UDF Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 8, 2014 Author Share Posted January 8, 2014 Glad that I could help. By the way I found out through some experiments, that the windows on such a hidden desktop will not render their DCs ( device context ) so for automation with image regognition unfortunately you will have to switch to that desktop or get the window to the current desktop which I will describe another time. regards Blues My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
joseLB Posted January 8, 2014 Share Posted January 8, 2014 Thanks Bluesmaster, I will check soon, and post here. But for your topic just above seems it will not work, correct? Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 9, 2014 Author Share Posted January 9, 2014 So I made some other experiments. It turns out, that neither pixelGetColor pixelSearce or any other device context operation can gather graphical information from the hidden desktop even if you manually send paint messages So unfortunately my udf is not appropriate for graphical operations and image regognition. I would recommend for that - virtual machines - out of monitor region ( manual repaint ) So far. best regards joseLB 1 My UDF: [topic='156155']_shellExecuteHidden[/topic] Link to comment Share on other sites More sharing options...
joseLB Posted January 13, 2014 Share Posted January 13, 2014 Bluesmaster, thanks a lot for your answers ! I will see if virtual machine is a valid option on my situation. I just don´t know what´s out of monitor region ( manual repaint ) Thanks Jose Link to comment Share on other sites More sharing options...
Bluesmaster Posted January 13, 2014 Author Share Posted January 13, 2014 I mean if you want to automate your window while the user can continue working you can place it outside your Monitor reach Lets say you place it on x = 4000 y=4000 But if you Need graphical Information ( lets say you must click on a Point that is in a certain color ) then you must send a "wm_paint" message to the window manually because Windows does not repaint Windows outside the Monitor reach regards Blues joseLB 1 My UDF: [topic='156155']_shellExecuteHidden[/topic] 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