BATCH file reloading autorun buffer - batch-file

There are things that we prefer not to understand in order to have an easier life to live.
But this is not something I can choose...
I made a batch file (or macro.doskey) to get the charset code. And it worked perfectly for a long time...
Basically it runs chcp:
> chcp
Code page active: 850
and then wraps the return before and after the colon
assigning what comes after to a variable:
FOR /F "tokens=1,* delims=:" %%s in ('CHCP') do (
#ECHO %%t
IF NOT "%1" == "" (SET %1=%%t)
)
For example:
> getCHCP.bat myVar
850
> ECHO %myVar%
850
However it started to lock, waiting for ENTER or displaying several echo messages. For example:
> getchcp myVar
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
850
I started to mix until I decided to change the ECHO %%t to ECHO %%s, and guess what?
No, is that the Bill Gates skull? Is it an easter egg from Microsoft? A virus?
No, none of that, this is just my autorun's welcome message.
This can be configured in
<[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]autorun>
In my case I called a batch file which, among other things, gives several echos showing this skull on the screen.
But the question is, why does it act like it reloads the autorun in background
when I've already opened the command prompt?
And why does it leave
everything in the buffer so that %%s pulls it again to the (Page code active) ':'?
And why are
you giving lots of ECHO is off on %%t when the only thing after
Code page active: is a number?
And the most important: How I solve it?

It's obvious, you already point to the problem.
this is just my autorun's welcome message.
This can be configured in
<[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]autorun>
The line FOR /F %%s in ('CHCP') ... start CHCP but that will be done in a NEW child cmd.exe instance.
And a NEW cmd.exe instance runs the autorun command!
Just before it starts your chcp.
You can disable the autorun at all, or add some code to detect the difference between a new cmd.exe instance for the user against a new instance from a FOR /F.
Put this code at the start of your autorun batch file
#echo off
setlocal EnableDelayedExpansion
REM *** ALWAYS make a copy of the complete CMDCMDLINE, else you destroy the originial!!!
set "_ccl_=!cmdcmdline!"
REM *** %1 contains only data, when the script itself was called from the command line
if "%~1" NEQ "" (
goto :direct_call
)
REM *** The check is necessary to distinguish between a new cmd.exe instance for a user or for a "FOR /F" sub-command
if "!_ccl_:~1,-2!" == "!comspec!" (
REM ***** INTERACTIVE ****
REM *** Show your skull or something else
)
exit /b

Related

Batch command mixing syntax during execution

I have tried to add a variable into an already existing batch file that I have written. However, when using the new command with the variable the command gets jumbled up.
How it supposed to work.
A user is prompted for an input (one of 3 letters). The input dictates the root directory used for a software execution. This section of code pulls a list of .elf files and is supposed to write them to a .txt file in the root directory.
Issue.
When using the variable directory, the .txt file and directory are switched during execution.
Original (Works)
DIR \\somepath\%VAR%\*.elf /b /o-s>C:\MyRootFolder\unlk.txt
New command with 2nd variable (acts strangely)
DIR \\somepath\%VAR%\*.elf /b /o-s>%root%\unlk.txt
but executes like this!?
DIR \\somepath\25091562033-00\*.elf /b /o-s \unlk.txt 1>C:\MyRootFolder
I am trying to have my root folder selected by an input further up because there are 3 different versions of software that I need to use to perform an operation. Being able to have the folder selected by an input would make things a lot easier.
Any ideas of why this executes semi-backwards?
Edit:
Here is the first section of my batch file all the way down to where the error happens. I have removed some of the code that doesn't relate to the issue. Note that the excessive pauses are for troubleshooting and the section which sets the variable %ECUPN% has been removed as it is working as intended.
ECHO off
:Ask
CLS
ECHO What type of processor does this ECU have?
ECHO F = Freescale_Quasar
ECHO T = TI
ECHO M = Motorola
SET INPUT=
SET /P INPUT=[F/T/M]: %=%
IF /I "%INPUT%"=="F" SET root=C:\Freescale_Quasar && GOTO :Fetch
IF /I "%INPUT%"=="T" SET root=C:\TI_MK100 && GOTO :Fetch
IF /I "%INPUT%"=="M" SET root=C:\MK100_Motorola && GOTO :Fetch
GOTO :Ask
:Fetch
CLS
Echo on
ECHO Fetch
pause
DIR \\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\*.elf /b /o-s>%root%\unlk.txt
pause
SET /P Code=<%root%\unlk.txt
pause
COPY "\\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\%Code%" "%root%\unlock.elf" || GOTO :error_1
pause
ECHO App = %code%>>C:\Unlock\log.txt
pause
GOTO :Build_1

My Batch file loop stops because of open file

I am trying to build a batch file that pings multiple devices on our network and continues logging ping results data in an output file in an infinite loop. However, the infinite loop gets hung up because the output file is open. Once I manually close the output file, the loop begins another iteration and logs more data. How do I automate this step? I've gone through so many options with taskkill, but none of them will close the output file for some reason. Other Notepad files close, but not the output file running on notepad.
Thanks for you help! Code is below:
#echo off
if exist C:\Users\Tsgadmin\Desktop\data\computers.txt goto Label1
echo.
echo Cannot find C:\Users\Tsgadmin\Desktop\data\computers.txt
echo.
Pause
goto :eof
:Label1
:loop
echo ================================================= >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
echo PingTest executed on %date% at %time% >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
for /f %%i in (C:\Users\Tsgadmin\Desktop\data\computers.txt) do call :Sub %%i
notepad C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
choice /n/t:c,<10>/c:cc
echo ================================================= >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
echo. >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
start notepad.exe
for /f "tokens=2" %%x in ('tasklist ^| findstr notepad.exe') do set PIDTOKILL=%%x
taskkill /F /IM notepad.exe > nul
goto loop
goto :eof
:Sub
echo Testing %1
ping -n 1 %1 >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt | find /i "(0% loss)"
echo %1 Testing done
echo %1 Testing done >> C:\Users\Tsgadmin\Desktop\ping_firepanels_output.txt
Here is your batch code rewritten for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "LogFile=%USERPROFILE%\Desktop\ping_firepanels_output.txt"
set "ListFile=%USERPROFILE%\Desktop\data\computers.txt"
if exist "%ListFile%" goto PrepareForPings
echo/
echo Cannot find file: "%ListFile%"
echo/
endlocal
pause
goto :EOF
rem Delete existing log file before running the echo requests.
rem Get just file name with file extension without path from
rem log file name with path specified at top of the batch file.
:PrepareForPings
del "%LogFile%" 2>nul
for /F %%I in ("%LogFile%") do set "LogFileName=%%~nxI"
rem Always terminate (not kill) running Notepad instance with having
rem the log file opened for viewing before running first/next test run.
:PingLoop
%SystemRoot%\System32\taskkill.exe /FI "WINDOWTITLE eq %LogFileName% - Notepad" >nul 2>nul
echo =================================================>>"%LogFile%"
>>"%LogFile%" echo PingTest executed on %DATE% at %TIME%
echo/>>"%LogFile%"
for /F "usebackq" %%I in ("%ListFile%") do (
echo Testing %%I ...
%SystemRoot%\System32\ping.exe -n 1 -w 500 %%I>nul
if errorlevel 1 (
echo %%I is not available in network (no reply^).>>"%LogFile%"
) else echo %%I is available.>>"%LogFile%"
echo %%I testing done.
)
echo =================================================>>"%LogFile%"
echo/>>"%LogFile%"
start "" %SystemRoot%\notepad.exe "%LogFile%"
echo/
%SystemRoot%\System32\choice.exe /C NY /N /T 10 /D Y /M "Run again (Y/n): "
echo/
if errorlevel 2 goto PingLoop
endlocal
In general it is advisable to define environment variables with names of files specified multiple times in the batch file at top to make it easier to modify them in future.
On referencing those file environment variables it is strongly recommended to enclose the name in double quotes to get a working batch file also when file name with path contains a space character or one of these characters: &()[]{}^=;!'+,`~
If a file name enclosed in double quotes is specified as text file of which lines to read in a for /F command line, it is necessary to use option usebackq to get interpreted the file name enclosed in double quotes as file name and not as string to process by FOR.
The DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ explains why it is better to use echo/ instead of echo. to output an empty line.
The TASKKILL command used to send Notepad the terminate signal for a graceful termination should be send only to the Notepad instance having the log file opened and not any other perhaps running Notepad instance.
An ECHO line redirected to a file with > or >> with a space left to redirection operator results in having this space also written as trailing space into the file. For that reason there should be no space between text to write into the file and redirection operator. A space right to > or >> would be no problem as not written into the file.
When a variable text is output on an ECHO line redirected into a file which could end with 1, 2, 3, ... 9, it is necessary to specify the redirection from STDOUT into the file with >> at beginning of the line as otherwise 1>>, 2>>, ... would be interpreted different as expected on execution of the ECHO command line. Read also the Microsoft article about Using Command Redirection Operators.
There is no subroutine necessary for this task. A command block starting with opening parenthesis ( and matching ) can be used here too. That makes the execution of the loop a bit faster, not really noticeable faster, but nevertheless faster.
There is a text written with echo into the log file containing also a closing parenthesis ) not within a double quoted string. This ) would be interpreted as matching ) for opening ( of true branch of IF condition. It is necessary to escape ) with caret character ^ to get ) interpreted as literal character by Windows command interpreter.
PING exits with exit code 1 if the echo request was not replied. Otherwise on successful reply the exit code is 0. It is better to evaluate the exit code via errorlevel than filtering the language dependent output.
New instance of Notepad with the log file to view is started by this batch file using command start to run Notepad in a separate process running parallel to command process executing the batch file. Otherwise the execution of the batch file would be halted as long as the started Notepad instance is not closed by the user. That different behavior can be easily seen on removing start "" at beginning of the command line starting Notepad.
The command CHOICE gives the user of the batch file the possibility to exit the loop by pressing key N (case-insensitive) within 10 seconds. Otherwise the user prompt is automatically answered with choice Y and the loop is executed once again by first terminating running Notepad.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
del /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
ping /?
set /?
setlocal /?
start /?
taskkill /?
See also Windows Environment Variables for details on environment variables USERPROFILE and SystemRoot as used in this batch file.

Batch script to move to another section of the script if there is no input from user

I am trying to get this script to jump to another section of the script if there is no input from the user.
Down at the if %input%== area.
What I'm trying to do is skip to the section where the script checks for .mp4 files and moves them if they are there. Am I supposed to set a variable or loop for that section? Thanks for any replies
#echo off
echo Checking for youtube-dl updates.
pause
youtube-dl -U
rem Enter the url or urls that you want to download from
set /p input="Enter the url(s) you want to download:"
rem Uses the youtube-dl continue (-c) option to download multiple files if not in a playlist
youtube-dl -c "%input%"
rem pause
if %input%=="" GOTO:EOF
cls
echo Download complete, please wait while files are transfered to appropiate folder
pause
for %%o in (.mp4) do move "*%%o" "E:\Documents\scripts\videos\"
if not exist do echo .mp4 files are no longer in this directory
pause
How about following script? This script waits for 3 seconds while "file.mp4" doesn't exist. It keeps to wait until the file exists. About "filename", you can change for your script.
#echo off
set waittime=3
set filename=file.mp4
:loop
if not exist %filename% (
Timeout /t %waittime% /nobreak > nul
goto loop
)
echo Find %filename%
When doing string comparison in batch you have to make sure, that both parts are equal, which in your case will never happen! In most languages strings have double quotes around them. In batch they usually do not.
To solve your problem enclose %input% in double quotes as well.
Note that it can be useful to do something like "x%input%"=="x" to prevent certain characters like <>|to be at the beginning of the comparison string.
You can check this on your own with these few lines:
#echo off
set /p input="Input something or nothing here "
echo %input%
echo "%input%"
pause
If you are hitting Return without any input you will see that only the bottom one will output "" which is the string you are comparing to.

How to use parentheses in .bat files, set command and IF EXIST

Ok, I have batch file, just a simple one that hides and unhides folders.
I don't see why it cannot seem to execute accordingly;
Here is extended sample code:
#echo off
color a
title Folder/Drive hider Service
:jiki
echo Loading...
TIMEOUT /T 2 >nul
goto inputs
:inputs
echo Enabling security...
TIMEOUT /T 2 >nul
cls
goto menu
:menu
if EXIST "%~dp0\Encryption" (set status=Folder is locked.)
if EXIST "%~dp0\Logan_Documents" (set status=Folder is unlocked, to open it, enter open as your `action.)`
cls
echo.
echo STATUS: %status%
echo.
echo ----------------------------------------
echo FOLDER PROTECTOR by Logan
echo ----------------------------------------
echo.
echo Lock = Lock the folder(s)
echo Unlock = Unlock the folder(s)
echo Credits = For more info
echo V = Display your current version
echo Exit = Close the program
echo.
echo ----------------------------------------
echo For more info, just ask Logan!
echo ----------------------------------------
echo.
echo Select your action, %USERNAME%.
echo.
set /p "menu=>"
if /I %menu%== lock goto lock
if /I %menu%== unlock goto unlock
if /I %menu%== credits goto credits
if /I %menu%== v goto version
if /I %menu%== exit goto exit
goto invalid
and also a lot more, and every time I go to execute the script, it just leaves the status variable blank.
Here's what I've tried.
Reconfiguring all variables through a port, which then sorts based on if exist. doesn't work, just leaves status blank.
Using different variables. (Kinda stupid but I didn't want to think that I have all these errors because of a small typo.) Still left error blank.
Appreciate all efforts to resolve my problem and get this program working!
-Logan
if exist should work fine exactly as you use it. You don't strictly need the quotes, since the names don't include spaces. Also you don't need the parentheses since it is a single command.
But then again, it should work with them as well (I actually tested this), so the only thing I can imagine is that the files or folders are not found because the script is running in the wrong directory. After all you use just the names without any path, so the current directory should contain those files.
The 'current directory' isn't necessarily the directory in which the script is saved. If you are in 'C:\Foo' and you call 'C:\Bar\Script.bat', the current directory will still be 'C:\Foo'. The same goes for starting scripts through a shortcut.
To try this, you can use echo %CD% in your script to echo the current directory.
As a possible solution, you can use %~dp0 to use the actual directory in which the batch script is saved, so you always have a starting point to start from:
REM Check if 'Encryption' exists in the same folder as the batch file.
if EXIST "%~dp0\Encryption" (set status=Folder is locked.)
probably neither of the ifs are true, maybe because the active directory is not what you think it is. you can test this easily by inserting a set status=none above the ifs. or insert dir to see what the scrips actually sees at this point.

Question about reliability of windows batch script

I got a quite long windows batch script. In the middle of it there's a section using appcmd to detect the root path of a site in my IIS. That section runs fine when executed standalone. But when I execute the whole batch, this section could fail to detect the site path once in a while. I am totally confused by this unreliability issue. Have anyone met this before?
Thanks
Solution
It seems that there's some delay between a variable declaration and its coming into effect. I changed the order of some part of the batch file and it runs fine so far. I must say, it's still weird.
As I don't know what type of problem you have in your unknown code, I can only show the known unpredicable or random behaviour in batch-files.
1- multiple tasks echo of line ends
Sometimes but not always the linefeeds and carriage returns are print as the ASCII-Chars 10/13 (a circle and a note) instead of begin a new line.
#echo off
if "%1"=="/second" (
call :task %2
goto :eof
)
(call "%~0" /second 1 >con ) | ( call "%~0" /second 2 )
echo END OF TASKS
goto :eof
:task
for /L %%n IN (1,1,10) DO (
echo This is task%1, output no %%n
ping -n 2 localhost > nul
)
goto :eof
2- Sometimes but not always an expansion of %~^LF crashes, then the command window closes immediatly.
#echo off
set critical_content=hello%%~^
echo No crash
for %%a in (1 ) do (
for %%x in (4) do (
rem #%critical_content%#
)
)

Resources