PhilHibbs Posted April 22, 2010 Share 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 Link to comment Share on other sites More sharing options...
PhilHibbs Posted April 22, 2010 Author Share 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 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