CarlD Posted August 3 Share Posted August 3 (edited) I recently noticed that ConsoleWrite can use ANSI escape sequences to output colorful text in a cmd.exe window running in Windows Terminal (WT), but not to a cmd.exe window running under Windows Console Host (WCH). In WT you see colorful text; in WCH the ANSI escape sequences are written out literally. This raises two questions: 1) What's different about WT? 2) It would be nice if there were a conclusive test to determine whether an AutoIt console script is running in WT or WCH. I've tried testing if @AutoItPID is a child process of WindowsTerminal.exe, but it isn't, even if the AutoIt console script is running in a WT tab -- so no joy. Any ideas? Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the cmd.exe window (default = Bright Yellow on Black) ; Compile AutoIt script as a console app! ; Colors work in Windows Terminal (WT), not in Windows Console Host ; So: Set Global $bANSI = 1 if script is running in WT If Not $bANSI Then ConsoleWrite($sTxt) Else ConsoleWrite(Chr(27) & "[" & $iFg1 & "m" & Chr(27) & "[" & $iBg1 & _ "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & Chr(27) & _ "[" & $iBg0 & "m") EndIf Return EndFunc ;==>_ConsoleWriteANSI Edited August 3 by CarlD Link to comment Share on other sites More sharing options...
Nine Posted August 3 Share Posted August 3 (edited) This is working for me : ConsoleWrite(_WinAPI_GetProcessName(_WinAPI_GetParentProcess (_WinAPI_GetParentProcess (@AutoItPID))) & @CRLF) gives : WindowsTerminal.exe or explorer.exe or Scite.exe Edited August 3 by Nine CarlD 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
CarlD Posted August 3 Author Share Posted August 3 7 hours ago, Nine said: This is working for me : ConsoleWrite(_WinAPI_GetProcessName(_WinAPI_GetParentProcess (_WinAPI_GetParentProcess (@AutoItPID))) & @CRLF) gives : WindowsTerminal.exe or explorer.exe or Scite.exe Thanks, this is helpful. On my system (Win 10 Pro v10.0.19045.4651), this returns "WindowsTerminal.exe" if Windows Console Host is the default terminal application. However, it returns "cmd.exe" if Windows Terminal is the default. I'm pressed for time just now, but a quick search did not turn up any way to determine the default terminal app programmatically. Will do some further research soon. Link to comment Share on other sites More sharing options...
argumentum Posted August 3 Share Posted August 3 (edited) #include <WinAPIProc.au3> _ConsoleWriteANSI("Hello there !." & @CRLF) ; as is, will need compilation for testing Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the cmd.exe window (default = Bright Yellow on Black) ; Compile AutoIt script as a console app! ; Colors work in Windows Terminal (WT), not in Windows Console Host ; So: Set Global $bANSI = 1 if script is running in WT Local Static $bANSI = Am_I_in_WT() ; only used here ?, keep it here ? If Not $bANSI Then ConsoleWrite($sTxt) Else ConsoleWrite(Chr(27) & "[" & $iFg1 & "m" & Chr(27) & "[" & $iBg1 & _ "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & Chr(27) & _ "[" & $iBg0 & "m") EndIf Return EndFunc ;==>_ConsoleWriteANSI Func Am_I_in_WT() ; WindowsTerminal.exe Local $n, $iParentPID = @AutoItPID For $n = 1 To 99 $iParentPID = _WinAPI_GetParentProcess($iParentPID) If $iParentPID = 0 Then ExitLoop If _WinAPI_GetProcessName($iParentPID) = "WindowsTerminal.exe" Then Return 1 Next EndFunc Spoiler pre-edit idea: #include <Array.au3> #include <WinAPIProc.au3> ; _GetParentProcessTree() example mod. _ArrayDisplay(_GetParentOfMine(), "_GetParentOfMine", "", 0, Default, "PID|Name|CommandLine") Func _GetParentOfMine($iPID = @AutoItPID) Local $iFound = 0, $n, $iParentPID = $iPID, $aList[100][3] $aList[0][0] = $iPID $aList[0][1] = _WinAPI_GetProcessName($iPID) $aList[0][2] = _WinAPI_GetProcessCommandLine($iPID) For $n = 1 To 99 $iParentPID = _WinAPI_GetParentProcess($iParentPID) If $iParentPID = 0 Then ExitLoop $aList[$n][0] = $iParentPID $aList[$n][1] = _WinAPI_GetProcessName($iParentPID) $aList[$n][2] = _WinAPI_GetProcessCommandLine($iParentPID) If $iFound = 0 And ($aList[$n][1] <> "AutoIt3.exe" And $aList[$n][1] <> "AutoIt3_x64.exe") Then $iFound = 1 $aList[$n][1] = '-->' & $aList[$n][1] & '<--' ; found my parent EndIf Next ReDim $aList[$n][3] Return $aList EndFunc ;==>_GetParentOfMine Edited August 3 by argumentum better CarlD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
CarlD Posted August 4 Author Share Posted August 4 (edited) I appreciate the sample code -- many thanks. In the meantime, I found a workaround that supports writing ANSI colorful text to the console in both Windows Terminal and Windows Console Host. The trick is to save the text to a temp file and then type the file. #include <File.au3> #include <FileConstants.au3> #include <Process.au3> Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the console ("TYPE tmp_file" method) ; Default color - Bright Yellow on Black background Local $h, $sTmpFn = _TempFile(@ScriptDir) $h = FileOpen($sTmpFn, $FO_BINARY + $FO_OVERWRITE) If $h < 0 Then Return ConsoleWrite($sTxt) If Not FileWrite($h, Chr(27) & "[" & $iFg1 & "m" & Chr(27) & _ "[" & $iBg1 & "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & _ Chr(27) & "[" & $iBg0 & "m") Then FileClose($h) Return ConsoleWrite($sTxt) EndIf FileClose($h) _RunDos("type " & $sTmpFn) FileDelete($sTmpFn) EndFunc ;==>_ConsoleWriteANSI Edited August 4 by CarlD argumentum 1 Link to comment Share on other sites More sharing options...
CarlD Posted August 5 Author Share Posted August 5 (edited) Another way -- no file required. BUT: does not work if text includes newlines! Edit: Here's a workaround for text that includes newlines. In the final analysis, the "TYPE temp_file" method is more compact and straight-forward. expandcollapse popup#include <Process.au3> #include <StringConstants.au3> _ConsoleWriteANSI("This is Line #1." & @CRLF) _ConsoleWriteANSI("This is Line #2." & @CRLF, 33, 104) _ConsoleWriteANSI("This is Line #3a," & @CRLF & "and this is Line #3b" & @CRLF, 41, 52) _ConsoleWriteANSI("This is Line #4." & @CRLF, 105, 35) Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the console ("ECHO" method) ; Reserved chars ^&|()<> must be "escaped" with ^ ; Default color - Bright Yellow on Black background Local $aLines, $iNL = 0, $sDummy = Chr(254) & Chr(15) & Chr(255) Local $aResvChar = StringSplit("^&|()<>", ""); "^" must come first! While StringRight($sTxt, 2) = @CRLF $sTxt = StringTrimRight($sTxt, 2) $iNL += 1 WEnd $sTxt = Chr(27) & "[" & $iFg1 & "m" & Chr(27) & _ "[" & $iBg1 & "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & _ Chr(27) & "[" & $iBg0 & "m" For $i = 1 To $aResvChar[0] $sTxt = StringReplace($sTxt, $aResvChar[$i], "^" & $aResvChar[$i]) Next If StringInStr($sTxt, @CR) Or StringInStr($sTxt, @LF) Then $sTxt = StringReplace($sTxt, @CRLF, $sDummy) $sTxt = StringReplace($sTxt, @CR, $sDummy) $sTxt = StringReplace($sTxt, @LF, $sDummy) $sTxt = StringReplace($sTxt, $sDummy, @CRLF) While StringLeft($sTxt, 2) = @CRLF ConsoleWrite(@CRLF) $sTxt = StringTrimLeft($sTxt, 2) WEnd $aLines = StringSplit($sTxt, @CRLF, $STR_ENTIRESPLIT) For $i = 1 To $aLines[0] _RunDos("echo " & $aLines[$i]) Next Else _RunDos("echo " & $sTxt) EndIf If $iNL > 1 Then For $i = 2 To $iNL ConsoleWrite(@CRLF) Next EndIf EndFunc ;==>_ConsoleWriteANSI Edited August 5 by CarlD Better code for leading & trailing newlines argumentum 1 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