Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#1
Post
by aGerman » 21 Sep 2021 10:31
There are control sequences that you can send to a virtual terminal emulator to request certain information. The response is written to the stdin which seems to make it quite difficult to read it in a Batch code. The example below is a small code which demonstrates what I'm talking about all along. It tries to capture the
Device Attributes. I've chosen this because also the V2 console (Win 10) sends a response to this request. (So, it's not necessary to have Windows Terminal or any other 3rd party terminal installed.)
My question: Is there a possibility to get the response string captured in a variable or file without any further user interaction? I'm pretty sure this can be done with the aid of another scripting language like PowerShell. However, I'd like to know if there is a pure Batch solution in the first place.
Steffen
Code: Select all
@echo off &setlocal
for /f %%i in ('echo prompt $E^|cmd') do set "ESC=%%i"
set "CSI=%ESC%[" &REM Control Sequence Introducer
set "wr=<nul set /p =" &REM write without new line
:::::::::::::::::::::::::::::::::::::::::::::::::::
echo(
echo Press [Enter] to capture the value ...
set "devattr="
:: send the sequence using the prompt of SET /P and use the behavior of SET /P to wait for input at the same time
:: however, the response isn't assigned without pressing Enter
set /p "devattr=%CSI%c"
echo "%devattr:~3,-1%"
pause
echo(
echo Press [Enter], [Ctrl]+[Z], [Enter] to capture the value ...
set "devattr="
:: send the sequence
%wr%%CSI%c
:: print the buffer of the console input device using TYPE
:: however, the input stream does not have an EOF which is the reason why [Ctrl]+[Z] is necessary to interrupt the stream processing
for /f "delims=" %%i in ('type conin$') do set "devattr=%%i"
echo "%devattr:~3,-1%"
pause
echo(
echo Press [Enter], [Ctrl]+[Z], [Enter] to capture the value ...
set "devattr="
:: send the sequence
%wr%%CSI%c
:: pretty much the same behavior here, the stream has no EOF and the copy command is waiting for more input
copy conin$ "devattr.~tmp"
<"devattr.~tmp" set /p "devattr="
del "devattr.~tmp"
echo "%devattr:~3,-1%"
pause
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#2
Post
by T3RRY » 21 Sep 2021 11:20
aGerman wrote: ↑21 Sep 2021 10:31
There are control sequences that you can send to a virtual terminal emulator to request certain information. The response is written to the stdin which seems to make it quite difficult to read it in a Batch code. The example below is a small code which demonstrates what I'm talking about all along. It tries to capture the
Device Attributes. I've chosen this because also the V2 console (Win 10) sends a response to this request. (So, it's not necessary to have Windows Terminal or any other 3rd party terminal installed.)
My question: Is there a possibility to get the response string captured in a variable or file without any further user interaction? I'm pretty sure this can be done with the aid of another scripting language like PowerShell. However, I'd like to know if there is a pure Batch solution in the first place.
Steffen
Code: Select all
@echo off &setlocal
for /f %%i in ('echo prompt $E^|cmd') do set "ESC=%%i"
set "CSI=%ESC%[" &REM Control Sequence Introducer
set "wr=<nul set /p =" &REM write without new line
:::::::::::::::::::::::::::::::::::::::::::::::::::
echo(
echo Press [Enter] to capture the value ...
set "devattr="
:: send the sequence using the prompt of SET /P and use the behavior of SET /P to wait for input at the same time
:: however, the response isn't assigned without pressing Enter
set /p "devattr=%CSI%c"
echo "%devattr:~3,-1%"
pause
echo(
echo Press [Enter], [Ctrl]+[Z], [Enter] to capture the value ...
set "devattr="
:: send the sequence
%wr%%CSI%c
:: print the buffer of the console input device using TYPE
:: however, the input stream does not have an EOF which is the reason why [Ctrl]+[Z] is necessary to interrupt the stream processing
for /f "delims=" %%i in ('type conin$') do set "devattr=%%i"
echo "%devattr:~3,-1%"
pause
echo(
echo Press [Enter], [Ctrl]+[Z], [Enter] to capture the value ...
set "devattr="
:: send the sequence
%wr%%CSI%c
:: pretty much the same behavior here, the stream has no EOF and the copy command is waiting for more input
copy conin$ "devattr.~tmp"
<"devattr.~tmp" set /p "devattr="
del "devattr.~tmp"
echo "%devattr:~3,-1%"
pause
Jeb's solved this one a while ago, solution at topic:
viewtopic.php?t=9454
A modified version of the above linked function that can be used to capture the return from the different supported sequences:
Code: Select all
@echo off & CD "%TEMP%"
RD "%~n0_run" 2> nul && Timeout 1 > nul
MD "%~n0_run"
PUSHD "%~n0_run"
Setlocal
for /F %%e in ('Echo(prompt $E^|cmd') do set "ESC=%%e"
call :get_response c c $Dev.Attribs
call :get_response 6n R $Cursor.pos
Set $
Endlocal
POPD
exit /b
:# Original Author : Jeb - https://www.dostips.com/forum/viewtopic.php?t=9454
:get_response <sequence> <terminator character> <ReturnVar>
:# Attribs 0c c
:# CursorPos 6n R
:# https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#query-state
set "response="
set pos=2
:_get_loop
REM *** VT request
<nul set /p "=%ESC%[%1"
FOR /L %%# in (1 1 %pos%) DO pause < CON > NUL
for /F "tokens=1 skip=1 eol=" %%C in ('"REPLACE /W ? . < con"') DO (
set "char=%%C"
)
set "response=%response%%char:?=%"
set /a pos+=1
if "%char%" NEQ "%2" goto :_get_loop
set "response=%response:~0,-1%"
set "%3=%response%" 2> nul
exit /b
Last edited by
T3RRY on 21 Sep 2021 11:31, edited 1 time in total.
-
T3RRY
- Posts: 250
- Joined: 06 May 2020 10:14
#4
Post
by T3RRY » 21 Sep 2021 11:34
No worries, Just glad I remebered something for once.