Console-UDF - lesen und schreiben in einer Konsole

  • AutoIt bietet seit längerem die Option, als Konsolen-Applikation zu kompilieren. Dabei wird jedoch nur die Ausgabe durch Standard-Befehle untersützt und diese auch nur ohne Sonderzeichen. Diese UDF erlaubt den Zugriff auf mehr Funktionen, funktioniert jedoch ebenfalls nur im kompilierten Zustand.

    Ein Beispiel:

    [autoit]

    #include "Console.au3"
    _Console_STARTUP()
    _Console_Write("Testkonsole." & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    _Console_Write("Prompt: ")
    MsgBox(0, '', _Console_Read())

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0, '', _Console_Ask("Noch eine Eingabe: "))

    [/autoit][autoit][/autoit][autoit]

    _Console_Pause()

    [/autoit]
  • btw: Wie kann man den Fenstertitel ändern?


    Vermutlich damit ;)

    [autoit]

    Func _Console_SetTitle($sTitle)
    ; ProgAndy
    Local $aRes = DllCall("kernel32.dll", "bool", "SetConsoleTitleW", "wstr", $sTitle)
    If @error Then Return SetError(1,0,0)
    Return $aRes[0]
    EndFunc

    [/autoit]
  • Sehr gute UDF.
    Endlich mal was anderes als immer nur ConsoleRead/Write
    Auch gut finde ich, dass man das Skript nicht als CUI exe kompilieren muss.
    MfG. PrideRage

    Meine Projekte:
    ClipBoard Manager (beendet)
    Gutes ClipBoard Verwaltungs Programm mit nützlichen Funktionen.

    HTML Creator (beendet)
    Nützliches Tool um schnell ein eigenes HTML Dokument zu erstellen.

  • Hallo,
    auch wenn dieses Thema schon etwas älter ist, habe ich eine Frage:
    Kann man irgendwie das schließen der Konsole mit dem "X" verhindern, oder kann man irgendwie eine Funktion definieren, die dann (= Beim Schließen der Konsole über das "X") aufgerufen wird?

    Viele Grüße
    Magnus

    Magnus

  • Gibt es vielleicht die möglichkeit das man überprüfen kann ob text in die console geschrieben wurde,
    allerdings ohne das das Script pausiert während auf die Rückgabe gewartet wird. Was in der Form von
    Tcprecv.

  • hier ist ne andere funktion ist aber kei eigengewächs

    Spoiler anzeigen
    [autoit]


    Global $re = _getDOSOutput('ftp -s:ftp.txt') ;hier können auch andere befehle rein
    MsgBox(64, '_getDOSOutput', StringStripWS($re, 7), 20)
    Func _getDOSOutput($command)
    Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2 + 4)
    While 1
    $text &= StdoutRead($Pid, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd
    Return $text
    EndFunc ;==>_getDOSOutput

    [/autoit]
  • Du hast mich falsch verstanden :D
    Ich meinte genau das selbe wie die Funktion "_Console_Read" aus dieser UDF , nur das
    sie falls nichts eingegeben wurde einfach "" zurück gegeben wird sodass das script nicht pausiert während auf die Eingabe
    gewartet wird.

  • Hi!

    Ich habe eine Frage. Die UDF als solches ist super und speziell die Funktion _Console_Pause funktioniert unter XP tadellos. Aber unter Win 8 64bit kann man in die Tasten hauen so viel man will, es passiert rein gar nichts.

    progandy, falls du das liest, könntest du versuchen herauszufinden, was da verkehrt läuft?

    Ich habe fast die gleichen Funktionen in einer eigenen Routine gehabt und gedacht, ich wäre einfach nur zu doof, das zu programmieren. Da du unzweifelhaft extrem fit bist, hab ich geglaubt, deine Routine wird's schon tun, aber sie zeigt genau das gleiche Verhalten. Microsofts MSDN liefert nichts brauchbares und auch Google schweigt sich dazu aus.

    Aber vielleicht fällt ja irgendwem was dazu sein, dann bitte immer her mit den Ideen! Ich habs schon mit anderen Funktionen wie ReadConsole, Handle öffnen über CreateFile mit CONIN$ und SetConsoleMode versucht, etc., aber nichts hilft... Alle Funktionen blocken irgendwie. So langsam verzweifel ich daran!

    Ich benötige eine Funktion, die genau EINEN Tastendruck nimmt, zurückkehrt und die gedrückte Taste als Rückgabewert hat UND die von XP bis Win8 funktioniert und leider liegt genau da das Problem.

    Lieber Gruss
    Holger

  • Hi!

    Habe die Lösung, falls es jemanden interessiert. Die Routine _Console_STARTUP muss etwas abgeändert werden:

    Spoiler anzeigen
    [autoit]


    ;Author: Prog@ndy
    Func _Console_STARTUP($ExitOnFatal = 0)
    If Not @Compiled Then
    If Not IsDeclared("_Console_USEWINDOW") Then
    #Region --- CodeWizard generated code Start ---
    ;MsgBox features: Title=Yes, Text=Yes, Buttons=Yes and No, Default Button=Second, Icon=Critical
    If 6 = MsgBox(276, "No Console App specified!", "You hav to copy these lines to your main-Script, just before you call _Console_STARTUP:" & @CRLF & "; These two lines, if the CMD-Console should be used, if possible" & @CRLF & " #AutoIt3Wrapper_Change2CUI=y" & @CRLF & " Global $_Console_USEWINDOW = True" & @CRLF & "; This line, if always a new Console should be created:" & @CRLF & " Global $_Console_USEWINDOW = False" & @CRLF & @CRLF & " COPY TO CLIPBOARD?") Then
    ClipPut("; These two lines, if the CMD-Console should be used, if possible" & @CRLF & _
    "#AutoIt3Wrapper_Change2CUI=y" & @CRLF & _
    "Global Const $_Console_USEWINDOW = True" & @CRLF & _
    "; This line, if always a new Console should be created:" & @CRLF & _
    ";~ Global Const $_Console_USEWINDOW = False")
    EndIf
    EndIf
    MsgBox(16, 'Console UDF error', "Console does not work in uncompiled scripts.")
    Exit
    EndIf
    If Not IsDeclared("_Console_USEWINDOW") Then Local $_Console_USEWINDOW = True
    If Not $_Console_USEWINDOW Then
    $ret = DllCall("Kernel32.dll", "long", "FreeConsole")
    $ret = DllCall("Kernel32.dll", "long", "AllocConsole")
    If $ret = 0 Then
    If $ExitOnFatal Then _WinAPI_FatalAppExit("Could not allocate Console")
    Return SetError(1, 0, 0)
    EndIf
    $HWND = DllCall("kernel32.dll", "hwnd", "GetConsoleWindow")
    WinSetState($HWND[0], "", @SW_SHOW)
    Else
    $ret = DllCall("Kernel32.dll", "long", "FreeConsole")
    $ret = DllCall("Kernel32.dll", "long", "AttachConsole", 'dword', -1)
    If $ret = 0 Then
    If $ExitOnFatal Then _WinAPI_FatalAppExit("Could not allocate Console")
    Return SetError(1, 0, 0)
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Global $GLOBAL_hConsole = _WinAPI_GetStdHandle(1)
    If $GLOBAL_hConsole = -1 Then
    If $ExitOnFatal Then _WinAPI_FatalAppExit("GetStdHandle for Output failed")
    Return SetError(2, 0, 0)
    EndIf
    DllCall("Kernel32.dll", "long", "SetConsoleActiveScreenBuffer", "handle", $GLOBAL_hConsole)
    Global $GLOBAL_hConsoleIn = _WinAPI_GetStdHandle(0)
    If $GLOBAL_hConsoleIn = -1 Then
    If $ExitOnFatal Then _WinAPI_FatalAppExit("GetStdHandle for Input failed")
    Return SetError(1, 0, 0)
    EndIf
    Return 1
    EndFunc ;==>_Console_STARTUP

    [/autoit]

    Die Zeilen 28-34 kommen dazu, Zeile 19 geändert, dann klappts.

    Liebe Grüße
    Holger

    Einmal editiert, zuletzt von pandel (28. April 2013 um 15:21)

  • Hi,

    auch wenn es etwas aus dem Rahmen fällt, aber unter Windows 10 Technical Preview funktioniert die Änderung nicht, da die Console direkt auf und wieder zu geht. Das nur rein zur Info, ich weiß ja nicht, wer sich schon mit Win10 beschäftigt ;)

    PS: anscheinend geht es doch, wenn man ein Timeout mitgibt und nicht default belässt.