My batch script doesn't use if command correctly - batch-file

I've spent a few days trying to get this batch script to work, but it just does not seem to work properly. It seems to just do whatever it wants after it prompts me to set a variable and i set it.
For example, I might enter n when it says that it doesn't seem to exist, and it will just end the script like it should. But if I re-open it, and it says the same thing as before, and I enter n again, it might just jump to :DeleteCalc, as if I typed y.
Here's my script:
#echo off
:Begin
color fc
title My script
cls
if not exist "C:\calc.exe" (
echo calc.exe doesn't seem to exist. Attempt deletion anyway? ^(Y/N^)
set "calcnotexist="
set /p "calcnotexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal EnableDelayedExpansion
if not !calcnotexist!==!calcnotexist:^"=! set "calcnotexist="
endlocal & if "%calcnotexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto Begin
)
if /i "%calcnotexist%"=="Y" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="Yes" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="N" goto End
if /i "%calcnotexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto Begin
)
:calcDoesExist
title My script
cls
echo calc.exe found. Delete? ^(Y/N^)
set "calcexist="
set /p "calcexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal enabledelayedexpansion
if not !calcexist!==!calcexist:^"=! set "calcexist="
endlocal & if "%calcexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto calcDoesExist
)
if /i "%calcexist%"=="Y" goto DeleteCalc
if /i "%calcexist%"=="Yes" goto DeleteCalc
if /i "%calcexist%"=="N" goto End
if /i "%calcexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto calcDoesExist
:DeleteCalc
cls
echo Deleting...
if not exist C:\calc.exe goto Success
del /f /q C:\calc.exe >nul 2>nul
if not exist C:\calc.exe goto Success
echo Fail!
echo.
echo calc.exe could not be deleted.
echo.
pause
goto End
:Success
echo Deleted!
echo.
echo calc.exe successfully deleted.
echo.
pause
goto End
:End
exit /b
What could I possibly be doing wrong?
Thanks
P.S. I tested this by opening CMD and running the batch script multiple times in there. (but it also doesn't work right when just double clicking it)

If you restructure your script there will be no need for the extended If blocks and therefore no necessity to EnableDelayedExpansion. Also if you use Choice you will not have to do all of the verification of responses.
Example:
#Echo Off
Title My script
Color FC
:Begin
If Exist "C:\calc.exe" GoTo calcDoesExist
Echo(calc.exe doesn't seem to exist.
Choice /M "Attempt deletion anyway"
If ErrorLevel 3 (ClS & GoTo Begin)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo Success
GoTo End
:calcDoesExist
Echo(calc.exe found.
Choice /M "Delete"
If ErrorLevel 3 (ClS & GoTo calcDoesExist)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo DeleteCalc
GoTo End
:DeleteCalc
ClS
Echo(Deleting...
Del /A /F "C:\calc.exe">Nul 2>&1
If Not Exist "C:\calc.exe" GoTo Success
Echo(Fail!
Echo(
Echo(calc.exe could not be deleted.
GoTo End
:Success
Echo(
Echo(Deleted!
Echo(
Echo(calc.exe does not exist.
:End
Echo(
Echo(Exiting...
Timeout 3 /NoBreak>Nul
Exit /B

Related

Why isn't error triggered IF/THEN working correctly?

Coding is just something I like to play with so I have limited knowledge and research hasn't helped. If I run the script I get both success and error messages instead of one or the other.
#ECHO OFF
SET /p HOSTFILE=Host File Name?&CLS
SET /p HIDEFILE=File To Hide?&CLS
SET /p OUTPUT=Output File Name?&CLS
SET /p EXTENSION=Output File Extension (.Zip, .Jpg, .M4A)?&CLS
COPY /b "%HOSTFILE%" + "%HIDEFILE%" %OUTPUT%%EXTENSION% >null
if %ERRORLEVEL% EQU 0 GOTO continue
if %ERRORLEVEL% EQU 2 GOTO error
:continue
ECHO %OUTPUT%%EXTENSION% Created.
:error
ECHO File Not Created.
TIMEOUT /T 2 >null
As Compo said in the comment you should probably check if your files exist.
when both hostfile and hidefile exist, a success message is indicated otherwise error message follows.
#ECHO OFF
SET /p HOSTFILE=Host File Name?&CLS
SET /p HIDEFILE=File To Hide?&CLS
SET /p OUTPUT=Output File Name?&CLS
SET /p EXTENSION=Output File Extension (.Zip, .Jpg, .M4A)?&CLS
IF EXIST "%HOSTFILE%" IF EXIST "%HIDEFILE%" (
echo exist hidefile
COPY /b "%HOSTFILE%" + "%HIDEFILE%" %OUTPUT%%EXTENSION% > nul
GOTO continue
)
) ELSE (
echo does not exist
GOTO error
)
:continue
ECHO %OUTPUT%%EXTENSION% Created.
GOTO timer
exit /b 0
:error
ECHO File Not Created.
GOTO timer
exit /b 0
:timer
TIMEOUT /T 2 > nul
exit /b 0

Batch: Show last user input

(This is my first post here, so bear with me)
Can you show the last user-input in a batch file? I'm gonna try to keep it simple here.
#echo off
:menu
echo Type 1 to proceed.
set /p example=
if "%example%" == "1" GOTO :proceed
GOTO :error
:proceed
pause
:error
cls
echo You wrote (last user input), that's not correct.
timeout 30
GOTO :menu
I know that I could replace the (last user input) with %example%, but then I'd have to make custom error messages for every category, and there are about 50 of them. It'd be easier with a last input command.
By the way, I've taught myself everything that I know about batch, so my example probably has major issues right now, but it works somehow.
You could centralize all user input into a function (user_input)
:menu1
echo Type 1 to proceed.
call :userInput example
if "%example%" == "1" GOTO :proceed
GOTO :error
:menu2
echo Type 42 to proceed.
call :userInput answer
if "%answer%" == "42" GOTO :proceed
GOTO :error
:userInput
set /p LAST_INPUT=
set "%1=%LAST_INPUT%"
exit /b
:proceed
pause
:error
cls
echo You wrote "%LAST_INPUT%", that's not correct.
timeout 30
GOTO :menu
I don't know how to do it without temp file. TO get the things written int the console you need the doskey /history (this will skip the running of the script itself):
#echo off
setlocal enableDelayedExpansion
set "last="
set "but_last="
doskey /history > log.txt
for /f "tokens=* delims=" %%# in (log.txt) do (
set "but_last=!last!"
set "last=%%#"
)
echo "%but_last%"
del /s /q log.txt >nul 2>nul

Batch IF doesn't work

I made a simple BATCH file for notes, it just deletes a folder, makes a new one, and puts in a file called note.txt and then edits it... for some reason, it doesn't do ANYTHING at all! not even removing the folder, here's the code:
goto start
:abort
ECHO Aborted!
PAUSE
GOTO start
:replace
del /q "D:\Users\Eldar\Desktop\Note Folder"
mkdir "Note Folder"
#echo>"D:\Users\Eldar\Desktop\Note Folder\note.txt"
#echo %note%> "D:\Users\Eldar\Desktop\Note Folder\note.txt"
pause
:start
#ECHO OFF
color e
cls
echo Put the note in here:
set /p LastNote=<"D:\Users\Eldar\Desktop\Note Folder\note.txt"
SET /P note=
cls
echo Note has been saved!
echo also, the last note you saved was: "%LastNote%".
echo so are you sure you want to replace this note with a new one (Y/N)?
SET /P agree=
IF "%agree%"=="y" (
ECHO goto replace
) ELSE (
GOTO abort
)
There are few errors in your script:
del can delete only empty folders. Use rmdir /s /q folder_name to remove folder with files
Remove ECHO in ECHO goto replace
You are using full paths everywhere except mkdir. Is it correct?
My working version:
#echo off
goto start
:abort
echo Aborted!
pause
goto start
:replace
rmdir /s /q ".\TestF"
mkdir "TestF"
echo>".\TestF\note.txt"
echo %note%> ".\TestF\note.txt"
pause
:start
color e
cls
echo Put the note in here:
set /p LastNote=<".\TestF\note.txt"
set /p note=
cls
echo Note has been saved!
echo also, the last note you saved was: "%LastNote%".
echo so are you sure you want to replace this note with a new one (Y/N)?
set /p agree=
if "%agree%"=="y" (
goto replace
) else (
goto abort
)
There appears to be no reason to remove the Note Folder directory or even to delete the note.txt file.
How does it perform if you rewrite it like this?
#Echo Off
Color 0E
Set "LastNote="
If Exist "%UserProfile%\Desktop\Note Folder\note.txt" (
Set/P LastNote=<"%UserProfile%\Desktop\Note Folder\note.txt"
)
If Not Defined LastNote GoTo replace
:ask
ClS
Echo=The last note you saved was:
Echo=%LastNote%
Echo=
Choice /M "Would you like to replace this note with a new one"
If "%ErrorLevel%"=="1" GoTo replace
Echo=
Echo=Aborted!
Timeout -1
GoTo ask
:replace
ClS
Set/P "note=Put the note in here: "
If "%note%"=="" GoTo ask
Echo=Note has been saved!
If Not Exist "%UserProfile%\Desktop\Note Folder\" (
MD "%UserProfile%\Desktop\Note Folder"
)
(Echo=%note%)>"%UserProfile%\Desktop\Note Folder\note.txt"
Timeout -1
GoTo ask
For the benefit of the OP, here is your version of your script with the major flaws removed and with unnecessary lines kept in.
#goto start
:abort
ECHO Aborted!
PAUSE
GOTO start
:replace
rmdir "D:\Users\Eldar\Desktop\Note Folder"
mkdir "D:\Users\Eldar\Desktop\Note Folder"
echo.>"D:\Users\Eldar\Desktop\Note Folder\note.txt"
>"D:\Users\Eldar\Desktop\Note Folder\note.txt" echo %note%
pause
:start
#ECHO OFF
color e
cls
echo Put the note in here:
set /p LastNote=<"D:\Users\Eldar\Desktop\Note Folder\note.txt"
SET /P note=
cls
echo Note has been saved!
echo also, the last note you saved was: "%LastNote%".
echo so are you sure you want to replace this note with a new one (Y/N)?
SET /P agree=
IF "%agree%"=="y" (
goto replace
) ELSE (
GOTO abort
)

How to find a certain word in a file without using ERRORLEVEL (batch)

I can use ERRORLEVEL, but tried and with a loop it failed.
I am writing a batch "shell."
Since I have tried and tried, I am finally asking for help.
The reason I don't want to use errorlevel is because the loop.
(FULL) SHELL
#set /p build=<"C:\Users\%username%\Desktop\WellOS2\WellOS\Build".txt
#title WellOS V.%build%
#echo off
goto boot
:register
cls
echo You are registering...
echo If this is an error press CTRL + C NOW...
pause
cls
set /p user= Enter your username:
set /p passwordreg= Enter your password:
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%"
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%\Documents"
echo %passwordreg% >"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
echo 2 >"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
echo Your done.
pause
goto welloslog
:booterror
echo Sorry the boot file has an error. Check the user manual for BOOT$
pause
:boot
set /p boot=<"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
if %boot% == 1 goto register
if %boot% == 2 goto welloslog
goto booterror
cls
:ERROR
cls
echo ----------ERROR-------------------
echo %error%
pause
goto %back%
:welloslog
cls
echo Welcome to WellOS2!
echo ----------------LOGIN-------------
set /p user= Username:
if exist "C:\Users\%username%\Desktop\WellOS2\Users\%user%" goto pass
set error= Sorry that account doesn't exist.
set back=welloslog
goto welloslogerror
:pass
set /p password=<"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
set /p passwordlog= Password:
if /i %passwordlog% == %password% goto wellos
set error= Sorry! wrong password.
set back= welloslog
goto error
:wellos
cls
:wellosnocls
echo --------------MAIN---------------
echo type help for help
set /p command= #:
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" set type=sys
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" set type=pro
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" goto po
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" goto po
set error= !Unreconized program/system program!
set back=wellos
goto error
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode"
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
PROGRAM OPENER (What I am talking about, and having problems with...)
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode" goto iftl
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
findstr "targetstring" datafilename >flagfilename
for %%a in (flagfilename) do if %%~za==0 echo not found
for %%a in (flagfilename) do if %%~za neq 0 echo found
beyond that, your question is too vague.
The following command returns all lines of a text file textfile.txt that contain the word word (remove the /I switch if you want the search to be case-sensitive):
findstr /I /L "word" "textfile.txt"
With for /F you can capture the output and test whether it is empty, as the loop does not iterate if no match is encountered:
set "FOUND="
for /F "delims=" %%F in ('
findstr /I /L "word" "textfile.txt"
') do (
set "FOUND=Yes"
)
if defined FOUND (
echo One or more matches found.
rem do something...
) else (
echo No match found.
rem do something else...
)
Type for /? and if /? in command prompt to get details about the used commands.
There is also a way to use ErrorLevel implicitly, meaning you do not have to query its value by something like %ErrorLevel%, !ErrorLevel! or if ErrorLevel, namely when using conditional command separators:
the && separator executes the following command only in case the previous one succeeded, that is, it returned an ErrorLevel of 0; (findstr returns 0 in case a match is encountered;)
the || separator executes the following command only in case the previous one failed, that is, it returned an ErrorLevel other than 0; (findstr returns a non-zero ErrorLevel in case no match is encountered;)
The following line of code demonstrates the usage:
findstr /I /L "word" "textfile.txt" && (echo One or more matches found.) || echo (No match found.)

Can only write one word on chat batch file

The code below is the part of my program. My problem is that when i enter my message it works perfectly if its 1 word. but if it is more it says goto was expected. the Q and R options are needed to refresh the chat and pop up a quit prompt.
set /p M=Enter Your Message:
if %M%==Q goto B
if %M%==q goto B
if %M%==R goto A
if %M%==r goto A
echo %U%: %M% >>%S%.txt
What should i do?
ps. this is my first quistion on here sorry if formating is wrong)
If the input has more than one word, the parser will see, after variable replacement
if this is a test==Q goto B
which is an invalid command.
Simplest solution is to use quotes
if "%M%"=="Q" goto B
....
will be interpreted as
if "this is a test"=="Q" goto B
edited to adapt to comments
This is a skeleton of a chat script with "auto update" in the terms indicated in the comments.
#echo off
setlocal enableextensions disabledelayedexpansion
rem Configuration
set "chatFile=c:\temp\chat.txt"
set "lastSize=-1"
:selectOption
rem Update screen
call :refresh
rem retrieve user selection
>nul choice /c rqw /n /t 3 /d r /m ""
rem Check what has been selected
if errorlevel 3 call :write & goto :selectOption
if errorlevel 2 goto :quit
rem Select another option
goto :selectOption
:refresh [bForceRefresh]
rem Check if refresh is being forced
if not "%~1"=="" set "lastSize=-1"
rem Ensure we have a file
if not exist "%chatFile%" >"%chatFile%" echo(
rem Check if we can skip the refresh.
rem If file has no changed its size there are no changes in content
for %%a in ("%chatFile%") do if %%~za leq %lastSize% (
goto :skipRefresh
) else (
set "lastSize=%%~za"
)
rem Paint the screen
cls
type "%chatFile%"
rem Show the options
echo(
<nul set /p ".=[R]efresh [Q]uit [W]rite ?"
:skipRefresh
goto :eof
:write
setlocal
rem Ask message
echo(
echo(
set "message="
set /p "message=What do you want to say? >"
rem If there is a message, write to output file,
rem else force screen refresh to remove the message question
if defined message (
setlocal enabledelayedexpansion
>>"%chatFile%" echo(%time% :[ %username% ]: !message!
endlocal
) else (
call :refresh forceRefresh
)
endlocal
goto :eof
:quit
cls
exit /b

Resources