#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include #include #include ;1st command line param that will launch seperate instance Const $hdiParam = 'hiddenDesktopInteract' ;######DO NOT PUT ANY OTHER CODE ABOVE THIS THAT CALLS A 2ND INSTANCE OF THE SCRIPT OR ELSE YOU MAY END UP CALLING INFINITE INSTANCES AND CRASHING WINDOWS!!!!!! ;seperate process for hidden desktop interaction ;1st param should be 'hiddenDesktopInteract' and 2nd param is name of func to call for interaction code ;ex: "autoit.exe script.au3 hiddenDesktopInteract interactionfunc" or "compiledscript.exe hiddenDesktopInteract interactionfunc" if $CmdLine[0] = 2 AND $CmdLine[1] = $hdiParam Then EXIT Call($CmdLine[2]) ;credit to Decipher in thread https://www.autoitscript.com/forum/topic/152515-start-a-process-hidden/#comment-1095173 for code for running process on a hidden desktop Func _hiddenDesktopInteract_run($sProgram, $sInteractionFunc, $sCommand = '') ;if the interaction function does not exist then don't do anything If Not IsFunc(Execute($sInteractionFunc)) Then ConsoleWrite('error: interaction function "' & $sInteractionFunc & '" for "' & $sProgram & '" does not exist' & @CRLF) Return EndIf ;create structs Local $tStartupInfo = DllStructCreate($tagStartupInfo) DllStructSetData($tStartupInfo, "Size", DllStructGetSize($tStartupInfo)) Local $tProcessInfo_targetApp = DllStructCreate($tagPROCESS_INFORMATION) Local $tProcessInfo_interactionScript = DllStructCreate($tagPROCESS_INFORMATION) ; Create Desktop Local $hDesktop = _WinAPI_CreateDesktop('AutoItHidden', BitOR($DESKTOP_CREATEWINDOW, $DESKTOP_SWITCHDESKTOP)) If Not $hDesktop Then MsgBox(0, 'Error', 'Unable to create desktop.') Exit EndIf ; Prep Process Info Local $nSuccess = DllStructSetData($tStartupInfo, "Desktop", _WinAPI_CreateString("AutoItHidden")) ;run target program on hidden desktop and get PID _WinAPI_CreateProcess('', '"' & $sProgram & '"' & ($sCommand ? ' ' & $sCommand : ''), 0, 0, 0, 0x00000200, 0, 0, DllStructGetPtr($tStartupInfo), DllStructGetPtr($tProcessInfo_targetApp)) Local $aPID_targetApp = DllStructGetData($tProcessInfo_targetApp, 'ProcessID') ConsoleWrite('!>target app PID:' & $aPID_targetApp & @CRLF) ;run instance of this script on hidden desktop to interact with target program Local $sParams = '"' & @ScriptFullPath & '" ' & $hdiParam & ' ' & $sInteractionFunc Switch @Compiled case True Local $sAppName = @ScriptFullPath Local $sCommandLine = $sParams case False Local $sAppName = @AutoItExe Local $sCommandLine = '"' & @AutoItExe & '" ' & $sParams EndSwitch _WinAPI_CreateProcess('', $sCommandLine, 0, 0, 0, 0x00000200, 0, 0, DllStructGetPtr($tStartupInfo), DllStructGetPtr($tProcessInfo_interactionScript)) ;and get PID of interaction instance so we can wait until it is finished Local $iPID_interactionScript = DllStructGetData($tProcessInfo_interactionScript, 'ProcessID') ConsoleWrite('!>Interaction Script PID: ' & $iPID_interactionScript & @CRLF) ;wait until interaction script instance is finished and get exit code (which is return value from interaction function) ProcessWaitClose($iPID_interactionScript) Local $exitcode_interactionScript = @extended ConsoleWrite("!>Interaction Script Exit Code: " & $exitcode_interactionScript & @CRLF) Local $sOutput = StdoutRead($iPID_interactionScript) ConsoleWrite("!>Interaction Script Stdout: " & $sOutput & @CRLF) ;close hidden desktop Local $aRet = DllCall("User32.dll", "int", "CloseDesktop", "handle", $hDesktop) ConsoleWrite("!>Close Desktop: " & $aRet[0] & @CRLF) ; Non-Zero is successfull! Return $exitcode_interactionScript EndFunc Func _hiddenDesktopInteract_cap($title, $imgfile, $Left = 0, $Top = 0, $Right = -1, $Bottom = -1) _GDIPlus_Startup() $hWnd = WinGetHandle($title) $iWidth = _WinAPI_GetWindowWidth($hWnd) $iHeight = _WinAPI_GetWindowHeight($hWnd) $hDDC = _WinAPI_GetDC($hWnd) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0) _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteDC($hCDC) $hBMPclone = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) if $Right = -1 then $iX = _GDIPlus_ImageGetWidth($hBMPclone) - $Left Else $iX = $Right - $Left EndIf if $Bottom = -1 then $iY = _GDIPlus_ImageGetHeight($hBMPclone) - $Top Else $iY = $Bottom - $Top EndIf ;convert from 32bit bitmap to 24bit bitmap b/c 32bit bitmap cannot display correctly in autoit GUI for some reason $hClone = _GDIPlus_BitmapCloneArea($hBMPclone, $Left, $Top, $iX, $iY, $GDIP_PXF24RGB) _GDIPlus_ImageSaveToFile($hClone, $imgfile) _WinAPI_DeleteObject($hBMP) _WinAPI_DeleteObject($hBMPclone) _WinAPI_DeleteObject($hClone) _GDIPlus_Shutdown() EndFunc