cmd.exe interprets ♪ as ? or ΓÖ¬ when reading .bat file on codepage 437 - batch-file

I wish to use the ♪ character inside a custom prompt for command prompt. This needs to be done from within my AutoRun batch file. chcp gives output Active code page: 437. If I type into the console via cmd.exe running on the Windows Terminal app prompt ♪$G, it works as expected, changing the prompt to ♪>.
However, if I type prompt ♪$G into a .bat file with vscode with encoding CP 437 or Windows 1252, the output is now:
prompt ?$G
?>
When saved with encoding UTF-8, the output is:
prompt ΓÖ¬$G
ΓÖ¬>
How can I change the prompt to ♪> from within a batch file? What encoding should the file be saved in? Will I need to use a hex editor in any way?

To use the ♪ character in a batch file, you need to save the file using the UTF-8 encoding.
You can do this in most text editors, including VS Code.
When you run the batch file, you may need to change the console code page to UTF-8 to ensure that the character is displayed correctly.
You can do this by adding the following line to your batch file:
chcp 65001
This will change the console code page to UTF-8. After that, you can set the prompt using the ♪ character as follows:
prompt ♪$G
This should set the prompt to ♪>.
You should not need to use a hex editor.
For example you can test with batch file below :
#echo off & cls
Chcp 65001>nul
prompt ♪$G
CMD /K
#echo on
This batch file sets up the command prompt with a custom prompt character and then launches a new instance of the command prompt with the /K switch, which keeps the new command prompt window open after executing any commands.
Here's a breakdown of the commands:
#echo off turns off the display of each command in the command prompt, so they are not displayed as they are executed.
cls clears the command prompt screen.
Chcp 65001 sets the console code page to UTF-8, so that it can display special characters like the music note symbol (♪).
prompt ♪$G sets the command prompt to display a music note symbol (♪) followed by a greater-than symbol (>) as the command prompt.
CMD /K launches a new instance of the command prompt and keeps it open.
#echo on turns on the display of each command in the new command prompt window.
Edit :
#echo off
REM Get the current code page and save it in the ORIGINAL_CODEPAGE variable
for /F "tokens=*" %%A in ('%SystemRoot%\System32\chcp.com') do for %%B in (%%A) do set /A "ORIGINAL_CODEPAGE=%%~nB" 2>nul
REM Display the original code page to the user and wait for a key press
echo My default current page is :%ORIGINAL_CODEPAGE%
pause
REM Set the console code page to UTF-8 (65001) and wait for a key press
chcp 65001
pause
REM Set the command prompt to display a musical note (U+266A) followed by a greater-than symbol and wait for a key press
prompt ♪$G
pause
REM Restore the original code page and launch a new command prompt that inherits the current environment variables
chcp %ORIGINAL_CODEPAGE%
CMD /K
Changing the console code page to UTF-8 (65001) can cause issues when piping text between applications that use the C standard library, as some of those applications may not support UTF-8 encoding.
This can result in characters being displayed incorrectly or not at all.
However, in the batch file I provided in the edit section, the original console code page is saved at the beginning of the batch file, and then restored at the end of the batch file using the chcp command.
This means that any negative side effects of changing the console code page to UTF-8 will be limited to the duration of the batch file, and the console code page will be restored to its original value before launching a new command prompt.
So, as long as you are only using the UTF-8 console code page within the batch file itself, and not piping text to other applications that do not support UTF-8, you should not experience any negative side effects.

Related

Why directing output of command to a variable doesnt work in batch file

I am trying to assign the output of the command python --version to a variable in batch script but it does not work.
Here is the sample code I am using
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
Although it prints the version for python, it does not assign to the variable var.
If I use another command instead of python --version then the output is correctly assigned. e.g. using dir works.
What could be wrong?
NOTE -
#echo off
set message=Hello
FOR /F "tokens=* USEBACKQ" %%F IN (`python --version`) DO (
SET message=%%F
)
ECHO %message%
PAUSE
OUTPUT -
C:\Users\nik>extra.bat
Python 2.7.9
Hello
Press any key to continue . . .
The installed version of Python outputs obviously the version information to handle STDERR (standard error) instead of handle STDOUT (standard output). For that reason it is necessary to redirect the standard error stream with the version information to standard output stream using 2>&1 as described by Microsoft in the documentation about Using command redirection operators.
The command line to use is:
for /F "delims=" %%I in ('python.exe --version 2^>^&1') do set "message=%%I"
The redirection operators > and & must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR.
FOR respectively cmd.exe processing the batch file with this command line starts in background one more command process with %ComSpec% /c and the command line specified within ' appended as additional arguments. Therefore is executed with Windows installed into C:\Windows in the background:
C:\Windows\System32\cmd.exe /c python.exe --version 2>&1
The command process in background searches now for an executable python.exe as described at What is the reason for "X is not recognized as an internal or external command, operable program or batch file"? When the file python.exe could be found by cmd.exe running in background without a visible console window, it executes it and Python outputs the version information to standard error stream which is redirected to standard output stream of the background command process.
The started cmd.exe closes itself after python.exe terminated itself after printing the version information.
The cmd.exe instance processing the batch file captures everything written to handle STDOUT of started background command process and FOR processes the captured lines after started cmd.exe closed itself.
There is split up by default a non-empty captured line into substrings using normal space and horizontal tab as string delimiters. If the first substring after removal of 0 or more leading spaces/tabs starts with a semicolon, the captured line is ignored, otherwise the first substring is assigned to the specified loop variable I.
The default line handling behavior is not wanted here. For that reason the for /F option delims= defines an empty list of string delimiters to disable the line splitting behavior to get the entire captured line assigned to the specified loop variable I. The implicit default eol=; (semicolon is end of line) can be kept in this case as the version information output by Python starts never with a semicolon.

Logging the output of a cmd window which is opened by another window

I am trying to log the outputs from a cmd window. I am running a bat file which is producing some outputs and I want to log them.
For example I am running the 'test.bat' file from cmd. This opens another cmd window and the output is displayed over there. I want to log the output of the second window.
If I write test.bat > result.log it only logs the terminating message from the 1st cmd window.
Any help or hint will be much appreciated.
These are the contents of the batch file (say test.bat) that I am trying to run from cmd
start CPU.bat
timeout /t 10
taskkill /IM api_test.exe /F
The contents of CPU.bat are
.\api_test.exe cpu -m "name_of_some_model_to_be_tested"
The simple solution is using as first command line:
start "CPU" %ComSpec% /C ""%~dp0CPU.bat" >"%UserProfile%\Desktop\CPU_Output.log" 2>&1"
This command line starts one more Windows command process with option /C to close this command process after execution of the specified command line finished. The console window opened gets the title CPU.
The started Windows command process executes the batch file CPU.bat which is in directory of the batch file containing this command line with full qualified file name. %~dp0 expands to full path of currently executed batch file always ending with a backslash and therefore concatenated with just CPU.bat to full qualified file name of this batch file.
The standard output of CPU.bat is redirected into the file CPU_Output.log in desktop directory of current user. The error output is redirected into the same file.
Please read the Microsoft article about Using command redirection operators for an explanation of > and 2>&1.
Open a command prompt window, run start /? and read the output help about this command. Next run cmd /? and read again the output help, especially the section about how the command line specified after option /C or /K is interpreted by Windows command processor which is very important here.
But CPU.bat is not needed at all on using this command line as first command line:
start "CPU" %ComSpec% /C ""%~dp0api_test.exe" cpu -m "name_of_some_model_to_be_tested" >"%UserProfile%\Desktop\CPU_Output.log" 2>&1"

Running External Commands on an .exe from a Batch Code

I am trying to run an .exe program entirely from batch commands. This program is in cmd prompt format (the .exe opens a command prompt and the user types in various commands to run). After using this command:
START /b [path] [.exe file]
The desired program is running in the command window. My problem arises next when the program prompts the user for commands (ex: "Enter Name - "). To these prompts I wish to respond with commands that will be recognized by the program (ex: to the prompt "Enter Name - ", I wish to respond "NAME" and click enter/return to display the next prompt).
I have tried using the echo command but after successfully printing what I want into the command line, I need the program to hit enter/return to move on to the next prompt. Any suggestions?
Thanks
The START command still admits stdin redirects. Therefore it should be possible for you to run,
START /b path\to\exe\file <path\to\canned\responses\file
For your specific case you could try,
#echo off
>tempinputfile echo reply foo
>>tempinputfile echo reply bar
start /b path\to\exe\file <tempinputfile

Use batch file to launch ssdeep with file arguments

I am attempting to use a looping batch file to launch the CMD app ssdeep and pass a file argument to it, then keep the ssdeep window open to copy a chunk of output to the clipboard I have the following code:
#ECHO OFF
:start
SET /p filetohash= What file would you like to fuzzy hash?
START C:\Users\Josh\Desktop\ssdeep-2.10\ssdeep-2.10\ssdeep.exe %filetohash%
PAUSE
goto start
This allows me to run the batch file, which I can then drag and drop a file to hash into the CMD window. Upon hitting return, the ssdeep CMD window appears for the moment it takes to hash the file, then closes. This leaves me with the 1st window generated by the batch file, that is requesting a key press.
I want to have the 2nd CMD window stay open so I can copy the hash out. Similar to the PAUSE I used in the batch file, but I need it to apply to the 2nd CMD window created.
I'm not exactly sure how to search for this information. I have searched info on batch files. I used these resources to get thus far:
https://superuser.com/questions/582095/how-to-create-a-batch-file-that-will-run-cmd-and-a-exe-with-parameters
and
Batch files : How to leave the console window open
Thanks in advance,
PTW-105
use the /b switch to the start command - see if that does what you need (leave the pause in).
start "" /b C:\Users\Josh\Desktop\ssdeep-2.10\ssdeep-2.10\ssdeep.exe %filetohash%
The empty double quotes protect the start command if you ever add quoted items in the commands.
Try this command to create hash.txt on your desktop - remove the pause - it should contain the information if it gets printed to STDOUT. It can be parsed to extract just the hash: if you add that information to your question it should be in a format that we can read and see how to parse it.
start "" /b C:\Users\Josh\Desktop\ssdeep-2.10\ssdeep-2.10\ssdeep.exe %filetohash% >"%userprofile%\desktop\hash.txt"

DOS batch argument substring in one line

I have a batch file with the following 2 lines and change them into one line of code:
set arg=%1%
"C:\Program Files\TextPad 6\TextPad.exe" -u "D:\www\%arg:~14,-1%"
The context is that I'm using a webpage url-handler as described on
http://msdn.microsoft.com/en-us/library/aa767914%28v=vs.85%29.aspx
Currently I'm doing it by setting the batch file as the url command, so the %1 is passed into that, then converted and then it runs the text-editor. But I'd rather do it all in the url command, so that I don't have to use the batch file any more.
After much trial & error, I found this works:
cmd.exe /v:on /c set arg=%1& start /D"C:\Program Files\TextPad 6" TextPad.exe "D:\www\!arg:~14,-1!"

Resources