Set ESC and BackSpace into variable using PROMPT

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Set ESC and BackSpace into variable using PROMPT

Post by MigrationUser »

05 May 2013 12:21
npocmaka

SetESC:

Code: Select all

@echo off
set prompt_backup=%prompt%
prompt $E
echo|set /p=^^^^>%temp%\prm.bat
setlocal enabledelayedexpansion
for /f "delims=" %%P in ('call %temp%\prm.bat 2^>nul') do (
        endlocal
        set esc_char=%%P
        rem echo %%P
        goto :end_for
)
:end_for
prompt %prompt_backup%
set "prompt_backup="
del %temp%\prm.bat /s /q >nul
SetBCKSP:

Code: Select all

@echo off
set prompt_backup=%prompt%
prompt $H
echo|set /p=^^^^>%temp%\prm.bat
setlocal enabledelayedexpansion
for /f "delims=" %%P in ('call %temp%\prm.bat 2^>nul') do (
        endlocal
        set bkps_char=%%P
        rem echo %%P
        goto :end_for
)
:end_for
prompt %prompt_backup%
set "prompt_backup="
del %temp%\prm.bat /s /q >nul
Does not work with $_ ...

Last edited by npocmaka (09 May 2013 15:37)

----------------------------

#2 05 May 2013 16:45
jeb

But you could also use this, without a temp file.

Code: Select all

for /F "tokens=1,2 delims=# " %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "BS=%%a"
  set "ESC=%%b"
)
Perhaps a bit shorter :)

----------------------------

#3 06 May 2013 09:15
npocmaka


That's pretty twisted - I like it !
(this %%b in the for /f call block has confused me at first :-) )
Unfortunately does not work with $+ (looks like FOR /F starts a new instance of cmd and there are no pushd-s)
BTW. My tests work with

Code: Select all

prompt #$E#$H#
, but not with

Code: Select all

prompt #$H#$E#
which is strange....

Last edited by npocmaka (06 May 2013 10:16)

----------------------------

#4 06 May 2013 17:53
Liviu
jeb wrote:

Perhaps a bit shorter :)
Following is a bit shorter even, though technically less efficient due to the extra cmd/k instance (EDIT: dropped unnecessary pipe from the code originally posted).

Code: Select all

for /f "tokens=1,2 delims=# " %%a in ('prompt #$E#$H# ^& cmd /k ^<nul') do (
  set "ESC=%%a"
  set "BS=%%b"
)
npocmaka wrote:

BTW. My tests work with prompt #$E#$H#, but not with prompt #$H#$E#
Appears to work either way if you remove the space after # in "tokens=1,2 delims=# ".

EDIT: On second thought, the space is necessary as a "delim", because $H inserts not just _one_ single BACKSPACE, but rather the sequence of BACKSPACE-SPACE-BACKSPACE. Guess this has to do with how the console works internally, for example it ensures that a BACKSPACE at the end of the string actually erases (writes a SPACE over) the previous character, not only moves the cursor one position to the left. The behavior can be verified with some simple code

Code: Select all

@echo off & setLocal

prompt #$H#$E#
echo on
echo off

prompt #$E#$H#
echo on
echo off
which if run, redirected to a file, and dumped in hex shows the actual BACKSPACE-SPACE-BACKSPACE sequence generated by $H.

Code: Select all

00000000  0D 0A 23 08  20 08 23 1B  23 65 63 68  6F 20 6F 66  ♪◙#◘ ◘#←#echo of
00000010  66 20 0D 0A  0D 0A 23 1B  23 08 20 08  23 65 63 68  f ♪◙♪◙#←#◘ ◘#ech
00000020  6F 20 6F 66  66 20 0D 0A                            o off ♪◙
What's still strange is that doing a "type" on the file above displays

Code: Select all

#←#echo off

##echo off
where the second line collapsed the whole "#<ESCAPE>#<BACKSPACE><SPACE><BACKSPACE>#" into a display of "##". Might be that BACKSPACE has special rules when the previous character is a control like ESCAPE.

Liviu

Last edited by Liviu (06 May 2013 23:39)

----------------------------

#5 08 May 2013 18:45
npocmaka


...and how TREE can be used to set some other symbols (jff):

Code: Select all

@echo off
pushd %windir%\System32\wbem
setlocal enabledelayedexpansion

for /f "tokens=1,2 delims=bg " %%a in ('tree^|findstr /e "d"') do (
	set line=%%b
	if not defined big_pipe set big_pipe=%%a
	if not defined leaned_t set leaned_t=!line:~0,1!
	if defined leaned_t set dl_angle=!line:~0,1!
	if not defined dash set dash=!line:~1,1!

)
rem echo  ~~!big_pipe!~~
rem echo ~~!leaned_t!~~
rem echo ~~!dl_angle!~~
rem echo ~~!dash!~~
endlocal
popd
----------------------------

#6 09 May 2013 05:38
foxidrive


It seem a good idea but it doesn't work on Win8 32 bit box. No output.

I don't know what you are parsing, to fix it.

----------------------------

#7 09 May 2013 08:05
npocmaka


This is the output that I'm trying to parse:

Code: Select all

C:\Windows\System32\wbem>tree | findstr /e "d"
│   ├───bad
│   └───good
I've just looking for a directory that has at least two other directories in it with a easy to filter them with FINDSTR od FIND.May be %windir%\System32\wbem is not so universal and in Win8 32 bit box
it does not have bad and good directories?

----------------------------

#8 09 May 2013 11:12
foxidrive


Here's an old school method - I wasn't sure of the names so I used a b c d

Code: Select all

@echo off
setlocal enabledelayedexpansion
:loop
set folder=%temp%\char_%random%
if exist "%folder%" goto :loop
md "%folder%"
pushd "%folder%"
md one\one
md two
for %%a in (a b c d) do set "%%a="
for /f "skip=3 delims=" %%a in ('tree') do (
	set line=%%a
rem        echo !line!
	if not defined a (
        set a=!line:~0,1!
        set b=!line:~1,1!
        ) else if not defined c (
        set c=!line:~0,1!
       	) else if not defined d (
        set d=!line:~0,1! 
        )
)
popd
rd /s /q "%folder%"
echo "%a%" "%b%" "%c%" "%d%"
pause
Last edited by foxidrive (09 May 2013 11:13)

----------------------------

#9 09 May 2013 13:12
npocmaka


but that will affect the performance....That's why I've searched for a universal dir structure in %windir%
With reading files (or creating a temporary ones) and counting on the `magic numbers` probably it will be possible to extract more extended ascii characters..

----------------------------

#10 10 May 2013 06:23
Liviu
npocmaka wrote:

...and how TREE can be used to set some other symbols (jff):
Just to nitpick, but the code should first 'chcp' to an OEM codepage (like 437, or 850) otherwise it will fail when run under ANSI codepages (like 1252). Following is the output from the code posted above with the echo lines un-commented, copied from an xp.sp3 cmd prompt set to a truetype font.

Code: Select all

C:\tmp>chcp 437
Active code page: 437

C:\tmp>tree-npocmaka
 ~~│~~
~~├~~
~~└~~
~~─~~

C:\tmp>chcp 1252
Active code page: 1252

C:\tmp>tree-npocmaka
 ~~³~~
~~Ã~~
~~À~~
~~Ä~~

C:\tmp>
Liviu

Last edited by Liviu (10 May 2013 06:26)

----------------------------

#11 10 May 2013 14:53
npocmaka


...and one based on identification characters (probably one of most ineffective ways to do it):

Code: Select all

@echo off
chcp 1252
for /f "delims= " %%A in ('type %windir%\inf\winusb.PNF') do (
	set line=%%A
	goto :end_for
)
:end_for
set "line="
set smile=%line:~0,1%
set heart=%line:~1,1%
set zmile=%line:~2,1%

echo %smile% %heart% %zmile%
these should be <EXT> <SOX> and something else...Should work on everything from XP and above.Any of the PNF files could be used.

Last edited by npocmaka (10 May 2013 14:56)
Post Reply