PhilHibbs Posted April 22, 2010 Posted April 22, 2010 (edited) I'm trying to convert this (scroll down to n-l-i-d's post) to AutoIt.This is my not-working AutoIt code:#include <WinAPI.au3> $pCmd = Run( "cmd.exe" ) $hCmd = _CmdGetWindow( $pCmd ) $hCon = _CmdAttachConsole( $pCmd ) msgbox( 0, "cmd", "Window = "& $hCmd & ", console = "& $hCon & ", error = " & @error ) Func _CmdGetWindow( $pCmd ) Local $WinList, $i While True $WinList = WinList() For $i = 1 to $WinList[0][0] If $WinList[$i][0] <> "" And WinGetProcess( $WinList[$i][1] ) = $pCmd Then Return $WinList[$i][1] EndIf Next WEnd EndFunc ;==>_CmdGetWindow Func _CmdAttachConsole( $pCmd ) Local $hConsole DllCall( "Kernel32.dll", "int", "AttachConsole", "int", $pCmd ) If @error Then Return SetError(1, 0, -1) $hConsole = DllCall( "Kernel32.dll", "hwnd", "CreateFile","str","CONOUT$", "int", 0xC0000000 _ , "int", 7, "int", 0, "int", 3, "int", 0, "int", 0 ) If $hConsole = -1 Then Return SetError( 2, 0, -1 ) Return $hConsole EndFunc ;==>_CmdAttachConsoleI'm getting nothing in the $hCon handle. The root of the problem is I don't really understand what the AttachConsole and CreateFile DLL calls do, or what the syntax should be to call them. For instance, what is that "CONOUT$" in the CreateFile call?*Update*: Just found Valik's Screen_Scrape.au3, I should be able to use that as a starting point instead of the <cough>AutoHotKey script. Edited April 22, 2010 by PhilHibbs
PhilHibbs Posted April 22, 2010 Author Posted April 22, 2010 (edited) OK I've had a go at cannibalising Screen_Scrape.au3. The original script won't compile since WinAPI.au3 no longer has a _WinAPI_MakeDWord function, and also I don't have 7Zip so I can't use it anyway. Here's my full script, which returns "0" instead of the screen contents. expandcollapse popup#include <WinAPI.au3> #include "VarDump.au3" Global Const $STD_INPUT_HANDLE = -10 Global Const $STD_OUTPUT_HANDLE = -11 Global Const $STD_ERROR_HANDLE = -12 Global Const $_CONSOLE_SCREEN_BUFFER_INFO = "short dwSizeX; short dwSizeY;" & _ "short dwCursorPositionX; short dwCursorPositionY; short wAttributes;" & _ "short Left; short Top; short Right; short Bottom; short dwMaximumWindowSizeX; short dwMaximumWindowSizeY" Global Const $_COORD = "short X; short Y" Global Const $_CHAR_INFO = "wchar UnicodeChar; short Attributes" Global Const $_SMALL_RECT = "short Left; short Top; short Right; short Bottom" $pCmd = Run( "cmd.exe" ) $hCmd = _CmdGetWindow( $pCmd ) $hCon = _CmdAttachConsole( $pCmd ) $cmdtext = _CmdGetText( $hCmd, $hCon ) MsgBox( 0, "text", $cmdtext ) Func _CmdGetWindow( $pCmd ) Local $WinList, $i While True $WinList = WinList() For $i = 1 to $WinList[0][0] If $WinList[$i][0] <> "" And WinGetProcess( $WinList[$i][1] ) = $pCmd Then Return $WinList[$i][1] EndIf Next WEnd EndFunc ;==>_CmdGetWindow Func _CmdAttachConsole( $pCmd ) Local $aRet = DllCall("kernel32.dll", "int", "AttachConsole", "dword", $pCmd) If @error Then Return SetError(@error, @extended, False) ; Return the handle on success. Return _CmdGetStdHandle($STD_OUTPUT_HANDLE) ; STDOUT Handle EndFunc ; _CmdAttachConsole() Func _CmdGetStdHandle($nHandle) Local $aRet = DllCall("kernel32.dll", "hwnd", "GetStdHandle", "dword", $nHandle) If @error Then Return SetError(@error, @extended, $INVALID_HANDLE_VALUE) Return $aRet[0] EndFunc ; _GetStdHandle() Func _CmdGetText( $hWin, $hConsole ) Local $bScrInfo = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO) ; Screen Buffer structure ; Try to get the screen buffer information. If _GetConsoleScreenBufferInfo($hConsole, $bScrInfo) Then ; Set up the coordinate structures. Local $coordBufferSize = _WinAPI_MakeDWord(4, 1) Local $coordBufferCoord = _WinAPI_MakeDWord(0, 0) Local $bRect = DllStructCreate($_SMALL_RECT) ; Load the SMALL_RECT with the projected text position. DllStructSetData($bRect, "Left", DllStructGetData($bScrInfo, "Left")) DllStructSetData($bRect, "Top", DllStructGetData($bScrInfo, "Top")) DllStructSetData($bRect, "Right", DllStructGetData($bScrInfo, "Right")) DllStructSetData($bRect, "Bottom", DllStructGetData($bScrInfo, "Bottom")) Local $iWidth = DllStructGetData( $bRect, "Right") - DllStructGetData( $bRect, "Left") + 1 Local $iHeight = DllStructGetData( $bRect, "Bottom") - DllStructGetData( $bRect, "Top") + 1 Local $bScrContent = DllStructCreate("dword[" & ($iWidth * $iHeight) & "]") ; Read the console output. ; We lie about the types for the COORD structures. Since they are the size of an int we expect a packed ; int. Otherwise we may crash or just pass garbage. Local $aRet = DllCall("kernel32.dll", "int", "ReadConsoleOutputW", _ "ptr", $hConsole, _ "ptr", _CmdSafeGetPtr($bScrContent), _ "int", $coordBufferSize, _ "int", $coordBufferCoord, _ "ptr", _CmdSafeGetPtr($bRect) ) If @error Then SetError(@error, @extended, False) If $aRet[0] Then ; This variable holds the output string. Local $sScreen = "" ; We iterate over 3 characters because that's all we read. For $i = 0 To $iHeight - 1 Local $sLine = "" For $j = 0 To $iWidth - 1 ; We offset the buffer each iteration by 4 bytes because that is the size of the CHAR_INFO ; structure. We do this so we can read each individual character. Local $pCharInfo = DllStructCreate($_CHAR_INFO, DllStructGetPtr($bScrContent) + ($i * 4)) ; Append the character. $sLine &= DllStructGetData($pCharInfo, "UnicodeChar") Next $sScreen &= StringStripWS( $sLine, 2 ) & @CRLF Next $sScreen = StringStripWS( $sScreen, 2 ) EndIf EndIf EndFunc ;==>_CmdGetText Func _GetConsoleScreenBufferInfo($hConsoleOutput, $pConsoleScreenBufferInfo) Local $aRet = DllCall("kernel32.dll", "int", "GetConsoleScreenBufferInfo", "hwnd", $hConsoleOutput, _ "ptr", _CmdSafeGetPtr($pConsoleScreenBufferInfo)) If @error Then Return SetError(@error, @extended, False) Return $aRet[0] EndFunc ; _GetConsoleScreenBufferInfo() Func _CmdSafeGetPtr(Const ByRef $ptr) Local $_ptr = DllStructGetPtr($ptr) If @error Then $_ptr = $ptr Return $_ptr EndFunc ; _SafeGetPtr() Func _WinAPI_MakeDWord($LoWORD, $HiWORD) Local $tDWord = DllStructCreate("uint34") Local $tWords = DllStructCreate("word;word", DllStructGetPtr($tDWord)) DllStructSetData($tWords, 1, $LoWORD) DllStructSetData($tWords, 2, $HiWORD) Return DllStructGetData($tDWord, 1) EndFunc ;==>_WinAPI_MakeQWordIt's failing in the _ReadConsoleOutput call, the ReadConsoleOutputW API returns 0 as the first array element, but it looks like Screen_Scrape.au3 does the same for me. Any ideas?Full output of the ReadConsoleOutputW call:[0] => Integer(0)[1] => Pointer(0x00000007)[2] => Pointer(0x015695C0)[3] => Integer(0)[4] => Integer(0)[5] => Pointer(0x0156A6E8)p.s. Yes I am compiling it.*Update:* I've installed 7Zip and tried ScreenScrape.au3 again and it isn't picking up the %, the progress bar doesn't appear until it's finished when it jumps to 100%. Edited April 23, 2010 by PhilHibbs
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