So i have this simple homework of doing a batch file that shows 3 options, and an error message for the entry for the option. so far it seems simple for me. I saw a youtube video and according to what i know it suppose to run ok but the problem is that when I run it and choose option 2 it opens also option 1, and when I choose option 3 it doesn't exit the program. And when I choose a parameter that is not specify the error message do not show. I am gonna copy paste my batch file because is easy to understand.
#echo off
echo Choose an option:
echo.
echo 1)Open Disk cleanup
echo 2)Open Disk Defragmenter
echo 3)Exit
echo.
Set /p Op=Write the option:
if %op%==1 (
start %windir%\system32\cleanmgr.exe
)
else if %op%==2 (
start %windir%\system32\dfrgui.exe
)
else if %op%==3 (
exit
)
else (
cls
echo Error not defined
)
pause
Is there something that I am missing or wrote wrong please let me know. If you can copy paste and run it in your computer and tell me if it is working fine because something tell me that in the process of learning I try a few times and i think I messed up with something that suppose to run correctly the file since my instructor told me that we have to be careful when using the commands in a batch file.
Your code formatted correctly but is susceptible to command injection because of the usage of the SET /P command.
#echo off
echo Choose an option:
echo.
echo 1)Open Disk cleanup
echo 2)Open Disk Defragmenter
echo 3)Exit
echo.
Set /p Op=Write the option:
if "%op%"=="1" (
start "" "%windir%\system32\cleanmgr.exe"
) else if "%op%"=="2" (
start "" "%windir%\system32\dfrgui.exe"
) else if "%op%"=="3" (
exit /b
) else (
cls
echo Error not defined
pause
)
A best practice solution which handles invalid input options.
#echo off
echo Choose an option:
echo.
echo 1)Open Disk cleanup
echo 2)Open Disk Defragmenter
echo 3)Exit
echo.
choice /C 123 /N /M "Select an Option:"
set "op=%errorlevel%"
if "%op%"=="1" start "" "%windir%\system32\cleanmgr.exe"
if "%op%"=="2" start "" "%windir%\system32\dfrgui.exe"
if "%op%"=="3" exit /b
I did it with this code.
#echo off
echo Choose an option:
echo.
echo 1)Open Disk Cleanup Utility
echo 2)Open Disk Defragmenter
echo 3)Exit
echo.
Set /p op/3=Write the number option:
if %op/3%==1 (
start %windir%\system32\cleanmgr.exe
)
if %op/3%==2 (
start %windir%\system32\dfrgui.exe
)
if %op/3%==3 (
exit
)
else (
cls
echo Error not defined
)
pause
the only problem that I have is that the error message appears even though options 1 and 2 are selected, it executes the options but it also shows the error message. I only want that the error message to show if any of those parameters aren't chosen.
I know that else is responding because if I choose option 1 else it executes because is not number 2 or 3. What it comes to my mind is if it is possible to define the op variable in an enumeration format like a group set of options.
Related
I am trying to write a bat file for a network policy that will install a program if it doesn't exist as well as several other functions. I am using GOTO statements depending on whether or not certain criterion are met. However, it seems that the labels are not firing correctly as all of them do.
I have simplified my script so as to grasp some idea of what may be happening.
#echo off
IF EXIST c:\test\test.txt (GOTO :EXISTING) ELSE GOTO :MISSING
:EXISTING
echo file exists
:MISSING
echo file missing
ping localhost -n 5 >NUL
Basically it checks to see that the file "test.txt" exists in folder "c:\test" which id does. So it should echo file exists to the console. However, both "file exists" and "file missing" are echoed to the console. I find that if I remove the file from the folder or simply rename it, it only echoes "file missing"
Why is it running running both labels?
Because a GOTO is just a jump in execution to a point in the script, then execution continues sequentially from that point. If you want it to stop after running 'EXISTING', then you need to do something like this. Note the extra GOTO and new label:
#ECHO OFF
IF EXIST c:\test\test.txt (GOTO :EXISTING) ELSE GOTO :MISSING
:EXISTING
echo file exists
goto :NEXTBIT
:MISSING
echo file missing
:NEXTBIT
ping localhost -n 5 >NUL
It's worth noting though that with cmd.exe (i.e., the NT-based command shells [NT, Win2k, XP, etc]), you can do IF...ELSE blocks like this:
#ECHO OFF
IF EXIST c:\test\test.txt (
ECHO File exists
) ELSE (
ECHO File missing
)
ping localhost -n 5 >nul
...so you can eliminate your GOTOs entirely.
It's because you need to skip over the "missing" bit if it exists:
#echo off
IF EXIST c:\test\test.txt (GOTO :EXISTING) ELSE GOTO :MISSING
:EXISTING
echo file exists
goto :COMMON
:MISSING
echo file missing
:COMMON
ping localhost -n 5 >NUL
You may also want to keep in mind that the current cmd.exe batch language is a fair bit more powerful than that which came with MS-DOS. I would prefer this one:
#echo off
if exist c:\test\test.txt (
echo file exists
) else (
echo file missing
)
ping localhost -n 5 >nul
After you echo file exists the next command is
echo file missing
You need to do something to skip the missing case. Perhaps another goto to a :PING label?
When you're debugging it helps to keep the echo on.
Because GOTO statement moves the execution to that label. To use it in the situation like yours, you need to add another GOTO label.
#echo off
IF EXIST c:\test\test.txt (GOTO :EXISTING) ELSE GOTO MISSING
:EXISTING
echo file exists
GOTO END
:MISSING
echo file missing
GOTO END
:END
ping localhost -n 5 >NUL
#echo off
IF EXIST "c:\test\test.txt" ( :: warning double quotes
GOTO EXISTING
) ELSE ( :: this format best in batch
GOTO MISSING
) :: don't forget
:EXISTING
echo file exists
goto OTHER :: if file exist jump OTHER
:MISSING
echo file missing
:: label is not required
:OTHER
timeout /t 5 >nul
pause
I am writing a basic batch script and I need to acquire user input.
The script appears to crash when I call the user input vars in an echo command.
(This is probably something very basic but I can't see the error...)
#echo off
echo ********************************
echo SHUTDOWN/RESTART
echo ********************************
echo.
set /p answer="Restart (R) or Shutdown(S)? "
set /p time="How soon ? "
echo you have selected %answer% in %time% seconds.
if "%answer%"=="" goto error
if "%time%"=="" goto error
if "%answer%"=="R" (
goto restart
) else (
goto shutdown
)
echo.
echo.
:restart
FOR /L %%AA IN (1,1,%1) DO (
echo Restarting in %%AA ...
)
The FOR command requires a single alphabetic character for its controlled variable. %AAA is invalid.
I looked for quite a while and couldn't find a good solution to my problem. I want a batch program to "look" in a .txt file for the command "" and if that word is in it, then to execute a different command. If the command existed, I would want to do something like set %textfile%=text.txt and if that worked I would then do if %textfile%==update goto update which would be an easy way to start an automatic update if this was in a loop. So basically, is there a command that sets a text file in %text%? This is the code that I am trying to add this into:
#echo off
color 0f
:start
echo Welcome to Master control pannel
ping 127.1 -n 4 >nul
cls
:options
cls
echo What would you like to do first? (Type the number of the operation you want to start)
echo.
ping 127.1 -n 2 >nul
echo 1. Run a command off of all computers
::(I want to run a command by sending a message to a text file but want recieving computor to be able to read it and execute it, how could I read the command and then do what it say, for example, if the command says "echo Hello" I would want recieving computor to say "Hello" )
echo 2. Stops the current command
echo 3. List all computers
echo 4. Open remote shutdown program
echo 5. Delete a computor (in progress)
echo 6. (Unfinished)
echo 7. (Unfinished)
echo 8. (Unfinished)
echo 9. (Unfinished)
echo 10. Exit
set /p choose=(1-9):
if %choose%==1 goto o1
if %choose%==2 goto o2
if %choose%==3 goto o3
if %choose%==4 goto o4
if %choose%==5 goto o5
if %choose%==6 goto close
if %choose%==7 goto close
if %choose%==8 goto close
if %choose%==9 goto close
if %choose%==10 goto o10
goto options
:close
cls
goto start
:o1
echo Stopping current command
del command.txt
echo. 2>command.txt
echo Command stopped!
pause
cls
goto start
I would greatly appreciate some help or comments to what I could do or add to this. Thanks!
Not an answer but several hints.
a variable can hold only single lines not a whole file.
if you want to get the first line of a file into a var use `Set /P "var="
set %textfile%=text.txt would store test.txt literally into a var whose name is the content of the var textfile.
you are mixing goto o1 and :01 with the label
`
This code is part of a chat program that I am currently working on. The 'else' part of my program is the one that doesn't work. The program quits instead of going to :home
:join
cls
if not exist "C:/Users/Public/room.cmd" (
echo No room has been found.
echo.
set /p choiceretry=Do you want to retry? y/n
if "%choiceretry%"=="y" goto join
if "%choiceretry%"=="n" goto home
) else (
cls
"C:/Users/Public/room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
echo %roomjoined%
goto home
)
:home
echo this finally works
pause
I have tried changing the code several times starting from 'echo Joining'
Anyone know why cmd quits?...
:) :) :)
Thanks in advance
The problem is the way you run room.cmd; you must use call to return from it:
call "C:/Users/Public/room.cmd"
Otherwise, execution will not return from room.cmd to the original batch file that ran it.
Hint: Consider to use choice instead of set /P for Y/N decisions.
Firstly, please don't left justify your code blocks. It's much easier to read code that's properly indented.
Secondly, when retrieving values within a code block, you need delayed expansion. See setlocal /? in a cmd prompt for more information. This is the reason for the unexpected behavior. Your variables retrieved within the same parenthetical code block in which they were set won't contain the values you expect unless you retrieve them with delayed expansion syntax. As an alternative, you could use the choice command and if errorlevel, which would result in a bit nicer user experience I think.
Thirdly, when testing user input, you should use the /i switch in your if statements for case-insensitivity. This isn't relevant if using choice / if errorlevel though.
Fourthly, Windows paths use backslashes, not forward slashes.
I'd fix it this way:
#echo off
setlocal
:join
cls
if errorlevel 1 set /P "=Retrying... "<NUL
if not exist "C:\Users\Public\room.cmd" (
echo No room has been found.
echo.
choice /c yn /n /m "Do you want to retry? [y/n] "
if errorlevel 2 goto home
goto join
) else (
"C:\Users\Public\room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
)
:home
echo this finally works
pause
I'm trying to make a short BAT file and I'm having trouble with one of its functions. I've tried a number of different ways to do this and none of them seem to work, but being a beginner at this I can't figure out the problem. Basically, the script, as it runs, is supposed to check if a certain .BAT file exists, and if it does, the script asks if the user wants to run it. If the user indicates Y, the other BAT is called and then the original script proceeds. If the user indicates N, the script is supposed to proceed without calling the other BAT. So far the script always notices and asks about the file, but choosing Y at the prompt never works. I'm sure the solution is obvious, but it's escaping me. Here's the code:
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\%kmname%\%kmname%.flt (
ECHO %kmname%.flt found, will now create %kmname%.ive.
CD C:\Visual\area\%kmname%\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "%kmpreproc%" EQU "Y" (
GOTO PREPROC
) ELSE (
GOTO CONTINUE
)
)
GOTO CONTINUE
) ELSE (
ECHO C:\Visual\area\%kmname%\%kmname%.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
)
:PREPROC
ECHO Running Preprocess.bat.
:CONTINUE
ECHO Continuing process.
PAUSE
The problem is your variables are being evaluated before they enter the if's, which means cmd won't see any changes until they have ended.
This is causing problems for you as your variables kmpreproc and, depending on the first if result, kmname change within the if blocks.
The fix (presuming the rest of your code is working) is to enable delayed expansion and use delayed expansion instead of normal expansion, by changing the %'s to ! on your variables.
setlocal enabledelayedexpansion
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\!kmname!\!kmname!.flt (
ECHO !kmname!.flt found, will now create !kmname!.ive.
CD C:\Visual\area\!kmname!\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "!kmpreproc!" EQU "Y" (
GOTO PREPROC
) ELSE (
GOTO CONTINUE
)
)
GOTO CONTINUE
) ELSE (
ECHO C:\Visual\area\!kmname!\!kmname!.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
)
:PREPROC
ECHO Running Preprocess.bat.
:CONTINUE
ECHO Continuing process.
PAUSE
Here is below my corrected and tided up code :
#echo off
SET /P kmname=Enter database name:
:kmstart
IF EXIST C:\Visual\area\%kmname%\%kmname%.flt (
ECHO %kmname%.flt found, will now create %kmname%.ive.
CD C:\Visual\area\%kmname%\
IF EXIST Preprocess.bat (
SET /P kmpreproc=Found Preprocess.bat. Do you want to run it now?
IF /I "%kmpreproc%"=="Y" (
GOTO PREPROC
)
GOTO CONTINUE
)
)
ECHO C:\Visual\area\%kmname%\%kmname%.flt does not exist. Try again.
SET /P kmname=Enter database name:
GOTO kmstart
:PREPROC
ECHO Running Preprocess.bat.
call "cmd /c start Preprocess.bat"
pause
:CONTINUE
ECHO Continuing process.
PAUSE
If it doesn't work try writting setlocal EnableDelayedExpansion under #echo off and replacing all % with ! .