Below is a .bat file with the code for a tic-tac-toe game for a class I am in. No matter what I change, I'm always greeted with "Invalid move. Please try again!" when entering a box location (eg, A1). The validation occurs in :ValidateResponse, starting in line 273. Can anyone see what I have done wrong causing this response? Thanks.
#ECHO off
REM ***************************************************************************
REM
REM Script Name: TicTacToe.bat
REM Author:
REM Date:
REM
REM Description: This is a Windows shell script implementation of the popular
REM child's game called "Tic-Tac-Toe".
REM
REM ***************************************************************************
REM ****** Script Initialization Section ******
REM Set the color scheme to yellow on black
COLOR 0E
REM Display the name of the game in the Windows command console's title bar
TITLE = T I C - T A C - T O E
REM Clear the display
CLS
REM ****** Main Processing Section ******
REM This label is called whenever the game needs to be restarted
:StartOver
REM Global variables used throughout the script
SET Player=X
SET Winner=None
SET /A NoMoves = 0
SET /A NoMoves = 0
REM Reset all the squares on the game board to show blanks
CALL :InitializeBlanks
REM Display the Welcome screen and prompt the players for instructions
CALL :Welcome
REM Process the player's instruction
IF /I "%reply%" == "" CLS & GOTO :StartOver
IF /I %reply% == Play CLS & CALL :Play
IF /I %reply% == Quit CLS & GOTO :EOF
IF /I %reply% == Help CLS & CALL :Help
IF /I %reply% == About CLS & CALL :About
GOTO :StartOver
GOTO :EOF
REM ****** Main Processing Section ******
REM Reset all squares on the game board to blanks
:InitializeBlanks
SET A1=
SET A2=
SET A3=
SET B1=
SET B2=
SET B3=
SET C1=
SET C2=
SET C3=
GOTO :EOF
REM Display the Welcome screen when called
:Welcome
REM Clear the display
CLS
REM Add 8 blanks lines to the display
FOR /L %%i IN (1,1,8) DO ECHO.
ECHO W E L C O M E T O T I C - T A C - T O E
ECHO.
ECHO.
ECHO Windows shell script style!
REM Add 9 blanks lines to the display
FOR /L %%i IN (1,1,9) DO ECHO.
REM Display a menu of options
ECHO Options: [Play] [Quit] [Help] [About]
ECHO.
REM Prompt the player to make a selection
SET /p reply=Enter selection:
GOTO :EOF
REM Display the game board
:DisplayBoard
REM Clear the display
CLS
ECHO.
ECHO.
ECHO T I C - T A C - T O E
ECHO.
ECHO.
ECHO.
ECHO 1 2 3
ECHO. Rules:
ECHO.
ECHO ^| ^| 1. Player X always goes first.
ECHO A %A1% ^| %A2% ^| %A3%
ECHO _____^|_____^|_____ 2. To make a move enter the
ECHO ^| ^| coordinates of the appropriate
ECHO B %B1% ^| %B2% ^| %B3% square.
ECHO _____^|_____^|_____
ECHO ^| ^| 3. Remember to switch turns when
ECHO C %C1% ^| %C2% ^| %C3% instructed by the game.
ECHO ^| ^|
ECHO.
ECHO.
ECHO.
ECHO Player %player%'s turn:
ECHO.
GOTO :EOF
REM Display the help screen when called
:HELP
REM Clear the display
CLS
REM Add 5 blank lines to the display
FOR /L %%i IN (1,1,5) DO ECHO.
ECHO HELP INSTRUCTIONS
ECHO.
ECHO.
ECHO This is a text-based implementation of the TIC-TAC-TOE game. In this game
ECHO the computer controls the action. Player X always goes first. The game
ECHO tells each player when it is his turn. When prompted to take a turn players
ECHO must type the coordinates of the square into which they wish to place their
ECHO marker (the X or O character). For example, to place a marker in the
ECHO upper left hand box, players would enter A1.
ECHO.
ECHO The game tracks the progress of each game and will automatically determine
ECHO when a game has been won, lost, or tied.
REM Add 6 blank lines to the display
FOR /L %%i IN (1,1,6) DO ECHO.
REM Make the player press a key to continue
PAUSE
GOTO :EOF
:About
REM Clear the display
CLS
REM Add 7 blank lines to the display
FOR /L %%i IN (1,1,7) DO ECHO.
ECHO About The TIC TAC TOE GAME
ECHO.
ECHO Written by
ECHO.
ECHO Jerry Lee Ford, Jr.
ECHO.
ECHO ------------------------
ECHO.
ECHO Copyright 2003
REM Add 7 blank lines to the display
FOR /L %%i IN (1,1,7) DO ECHO.
REM Make the player press a key to continue
PAUSE
GOTO :EOF
REM This procedure controls the actual play of the game
:Play
REM If player X has won then find out if a new game should be started
IF "%Winner%"=="X" (
CALL :DisplayGameResults
REM Make the player press a key to continue
PAUSE
GOTO :StartOver
)
REM If player O has won then find out if a new game should be started
IF "%Winner%"=="O" (
CALL :DisplayGameResults
REM Make the player press a key to continue
PAUSE
GOTO :StartOver
)
REM If the players tied find out if a new game should be started
IF "%Winner%"=="Nobody" (
CALL :DisplayGameResults
REM Make the player press a key to continue
PAUSE
GOTO :StartOver
)
REM display the game board
CALL :DisplayBoard
REM Collect current player's selection
SET /P response=Select a box:
REM Validate the specified selection
CALL :ValidateResponse
REM If the selection is valid
IF %ValidMove%==True (
REM Add 1 to the total number of valid selections made in the game
SET /A NoMoves = NoMoves += 1
REM Associate the player's selection with the right square
CALL :FillInSquare
REM If the player's selection is invalid
) ELSE (
REM Clear the display
CLS
REM Add 11 blank lines to the display
FOR /L %%i IN (1,1,11) DO ECHO.
ECHO Invalid move. Please try again!
REM Add 11 blank lines to the display
FOR /L %%i IN (1,1,11) DO ECHO.
REM Make the player press a key to continue
PAUSE
)
REM If a total of 9 valid selections have been made the board is full
IF %NoMoves% == 9 (
SET Winner=Nobody
) ELSE (
CALL :SeeIfWon
)
REM Its now time to switch players
IF %ValidMove%==True (
IF "%player%"=="X" (
SET Player=O
) ELSE (
SET Player=X
)
)
REM Loop back to the beginning and keep playing
GOTO :Play
GOTO :EOF
REM Ensure that the selection supplied by the player is valid
:ValidateResponse
REM By default assume a valid selection was made
SET ValidMove=True
REM Hitting enter without entering a selection is invalid
IF /I %response% == "" (
SET ValidMove=False
GOTO :EOF
)
REM Ensure that a valid square was specified (A1-A3, B1-B3 & C1 - C3)
IF /I NOT %response%==A1 (
IF /I NOT %response%==A2 (
IF /I NOT %response%==A3 (
IF /I NOT %response%==B1 (
IF /I NOT %response%==B2 (
IF /I NOT %response%==B3 (
IF /I NOT %response%==C1 (
IF /I NOT %response%==C2 (
IF /I NOT %response%==C3 (
SET ValidMove=False
GOTO :EOF
)
)
)
)
)
)
)
)
)
REM Previously selected squares are invalid
IF /I %response%==A1 (
IF NOT "%A1%"==" " (
SET ValidMove=False
)
)
IF /I %response%==A2 (
IF NOT "%A2%"==" " (
SET ValidMove=False
)
)
IF /I %response%==A3 (
IF NOT "%A3%"==" " (
SET ValidMove=False
)
)
IF /I %response%==B1 (
IF NOT "%B1%"==" " (
SET ValidMove=False
)
)
IF /I %response%==B2 (
IF NOT "%B2%"==" " (
SET ValidMove=False
)
)
IF /I %response%==B3 (
IF NOT "%B3%"==" " (
SET ValidMove=False
)
)
IF /I %response%==C1 (
IF NOT "%C1%"==" " (
SET ValidMove=False
)
)
IF /I %response%==C2 (
IF NOT "%C2%"==" " (
SET ValidMove=False
)
)
IF /I %response%==C3 (
IF NOT "%C3%"==" " (
SET ValidMove=False
)
)
GOTO :EOF
REM Associate the player's selection with the appropriate square
:FillInSquare
IF /I %response%==A1 SET A1=%player%
IF /I %response%==A2 SET A2=%player%
IF /I %response%==A3 SET A3=%player%
IF /I %response%==B1 SET B1=%player%
IF /I %response%==B2 SET B2=%player%
IF /I %response%==B3 SET B3=%player%
IF /I %response%==C1 SET C1=%player%
IF /I %response%==C2 SET C2=%player%
IF /I %response%==C3 SET C3=%player%
Goto :EOF
REM Display the results of the game
:DisplayGameResults
REM Clear the display
CLS
REM Set the default message to indicate a tie
SET messagetext=Tie - No Winner
REM If either player won set a variable containing a custom message
IF "%Winner%"=="X" SET messagetext=Player X has won!!!
IF "%Winner%"=="O" SET messagetext=Player O has won!!!
REM Add 5 blank lines to the display
FOR /L %%i IN (1,1,5) DO ECHO.
REM Display the final board and display a message indicating game results
ECHO ^| ^|
ECHO %A1% ^| %A2% ^| %A3% E N D O F G A M E
ECHO _____^|_____^|_____
ECHO ^| ^|
ECHO %B1% ^| %B2% ^| %B3% %messagetext%
ECHO _____^|_____^|_____
ECHO ^| ^|
ECHO %C1% ^| %C2% ^| %C3%
ECHO ^| ^|
REM Add 9 blank lines to the display
FOR /L %%i IN (1,1,9) DO ECHO.
GOTO :EOF
REM Check up, down, & diagonally to see if the player has won
:SeeIfWon
REM Check across
IF /I "%A1%"=="%player%" (
IF /I "%A2%"=="%player%" (
IF /I "%A3%"=="%player%" (SET Winner=%player%)
)
)
IF /I "%B1%"=="%player%" (
IF /I "%B2%"=="%player%" (
IF /I "%B3%"=="%player%" (SET Winner=%player%)
)
)
IF /I "%C1%"=="%player%" (
IF /I "%C2%"=="%player%" (
IF /I "%C3%"=="%player%" (SET Winner=%player%)
)
)
REM Check diagonally
IF /I "%A1%"=="%player%" (
IF /I "%B2%"=="%player%" (
IF /I "%C3%"=="%player%" (SET Winner=%player%)
)
)
IF /I "%A3%"=="%player%" (
IF /I "%B2%"=="%player%" (
IF /I "%C1%"=="%player%" (SET Winner=%player%)
)
)
REM Check up and down
IF /I "%A1%"=="%player%" (
IF /I "%B1%"=="%player%" (
IF /I "%C1%"=="%player%" (SET Winner=%player%)
)
)
IF /I "%A2%"=="%player%" (
IF /I "%B2%"=="%player%" (
IF /I "%C2%"=="%player%" (SET Winner=%player%)
)
)
IF /I "%A3%"=="%player%" (
IF /I "%B3%"=="%player%" (
IF /I "%C3%"=="%player%" (SET Winner=%player%)
)
)
GOTO :EOF
You have faulty logic in :ValidateResponse. I only answered the question you asked. This will allow you to move on to the next problem. Keep at it!
REM Ensure that a valid square was specified (A1-A3, B1-B3 & C1 - C3)
IF /I %response%==A1 GOTO :ContinueValidating
IF /I %response%==A2 GOTO :ContinueValidating
IF /I %response%==A3 GOTO :ContinueValidating
IF /I %response%==B1 GOTO :ContinueValidating
IF /I %response%==B2 GOTO :ContinueValidating
IF /I %response%==B3 GOTO :ContinueValidating
IF /I %response%==C1 GOTO :ContinueValidating
IF /I %response%==C2 GOTO :ContinueValidating
IF /I %response%==C3 GOTO :ContinueValidating
SET ValidMove=False
GOTO :EOF
:ContinueValidating
Then you also need to change all of the lines below that like the one below to change " " to "" because the variable is not initialized to a space.
IF NOT "%A1%"==" " (
to
IF NOT "%A1%"=="" (
Related
I've created a batch/cmd file which executes correctly, but I would like to add a "validation" layer to check for correct input.
The input should be in the format of LETTER-LETTER-######## (Eight Numbers)
I'm more of a Bash person myself so I'm a little lost.
Here is a basic version of what I am using.
echo Please Input like so XY########
set /P INPUT=Type input: %=%
Ok. Here we go...
There is no way to do what you want if you read the input via set /P command. In this case you may test the input afterwards and repeat it until be correct...
To check the input at same time it is being typed you need to read and test each character individually. There are several ways to do that. The simplest one is based on choice command:
#echo off
setlocal EnableDelayedExpansion
echo Please Input like so XY########
set /P "=Type input: " < NUL
set "INPUT="
rem Get two *UPPERCASE* letters
set "letter= ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for /L %%i in (1,1,2) do (
choice /C %letter% /N > NUL
for %%l in ("!errorlevel!") do set "INPUT=!INPUT!!letter:~%%~l,1!"
set /P "=!INPUT:~-1!" < NUL
)
rem Get eight digits
set "digit= 0123456789"
for /L %%i in (1,1,8) do (
choice /C %digit% /N > NUL
for %%l in ("!errorlevel!") do set "INPUT=!INPUT!!digit:~%%~l,1!"
set /P "=!INPUT:~-1!" < NUL
)
echo/
echo INPUT = "%INPUT%"
In this code:
Any letter pressed is converted to uppercase. This behavior may be cancelled including both upcase and lowcase letters in letter variable and adding /CS switch to choice command.
The last character input can not be deleted.
The input is automatically completed after the last character is input. No final ENTER key is needed.
If you want not this behavior and need more precise control on the input characters, then you must use another method; for example, reading the keys via xcopy trick. The link posted by Squashman above is an ample example on how to do that...
Aacini's answer also forces valid user input vs validating retroactilvey, his answer is less code and more "readable" IMO. I will be using his answer, but I figured I'd share this method.
I asked to "retroactively" validate user input, but #Squashmans commented URL forces valid user input in the first place.
https://www.dostips.com/forum/viewtopic.php?t=5775
Here is the "sanitized code" that I ended up with.
#echo off
#cls
::::START -- Section Blocks User from Inputting Invalid Data::::
setlocal
set "thisFile=%~F0"
call :ReadFormattedLine INPUT="__########" /M "Enter Input in Form XY########: "
echo/
:ReadFormattedLine var="mask" [/M "message"] [/P] [/F /W /A]
if "%~2" equ "" echo ERROR: Missing parameters & exit /B 1
setlocal EnableDelayedExpansion
set "var=%~1"
set "mask=%~2"
shift & shift
set "message="
if /I "%1" equ "/M" set "message=%~2" & shift & shift
set "password="
if /I "%1" equ "/P" set "password=1" & shift
set "switch=%~1"
set quote="
set "digit= 0 1 2 3 4 5 6 7 8 9 "
set "letter= A B C D E F G H I J K L M N O P Q R S T U V W X Y Z "
set "alphaNum=%digit%%letter%"
set "fmt=#_+?#"
set "show=$/\()[]:;,.- %digit: =%%letter: =%"
for /F %%a in ('copy /Z "%thisFile%" NUL') do set "CR=%%a"
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a" & set "SP=.%%a "
< NUL (
set /P "=%message%"
for /F "eol=| delims=" %%a in ('cmd /U /C echo !mask!^| find /V ""') do (
if "!fmt:%%a=!" neq "%fmt%" (
set /P "=Û"
) else if "%%a" neq " " (
set /P "=%%a"
) else (
set /P "=!SP!"
)
)
set /P "=!SP!!CR!%message%"
)
set "input="
set /A i=0, key=0
goto checkFormat
:nextKey
set "key="
for /F "delims=" %%a in ('xcopy /W "%thisFile%" "%thisFile%" 2^>NUL') do if not defined key set "key=%%a"
if "!key:~-1!" neq "!CR!" goto endif
if /I "%switch%" equ "/A" goto nextKey
if /I "%switch%" neq "/F" goto check/W
:nextField
set "format=!mask:~%i%,1!"
if "%format%" equ "" goto endRead
if "!fmt:%format%=!" equ "%fmt%" goto checkFormat
set /P "=Û" < NUL
set "input=%input% "
set /A i+=1
goto nextField
:check/W
if /I "%switch%" neq "/W" goto checkEmpty
if %i% equ 0 goto endRead
if "%format%" equ "" goto endRead
goto nextKey
:checkEmpty
if %i% gtr 0 goto endRead
goto nextKey
:endif
set "key=!key:~-1!"
if "!key!" equ "!BS!" (
if %i% gtr 0 (
if "%format%" equ "" (
set /P "=!SP!!BS!!BS!Û!BS!" < NUL
) else (
set /P "=Û!BS!!BS!Û!BS!" < NUL
)
set "input=%input:~0,-1%"
set /A i-=1
if !i! equ 0 set key=0
)
goto checkFormat
)
if "%format%" equ "" goto nextKey
if "!key!" equ "=" goto nextKey
if "!key!" equ "!quote!" goto nextKey
if "%format%" equ "#" ( rem Any digit
if "!digit: %key% =!" equ "%digit%" goto nextKey
) else if "%format%" equ "_" ( rem Any letter
if "!letter: %key% =!" equ "%letter%" goto nextKey
) else if "%format%" equ "+" ( rem Any letter, convert it to uppercase
if "!letter: %key% =!" equ "%letter%" goto nextKey
for %%a in (%letter%) do if /I "!key!" equ "%%a" set "key=%%a"
) else (
rem Rest of formats are alphanumeric: ? #
if "!alphaNum: %key% =!" equ "%alphaNum%" goto nextKey
if "%format%" equ "#" ( rem Convert letters to uppercase
for %%a in (%letter%) do if /I "!key!" equ "%%a" set "key=%%a"
) else if "%format%" neq "?" echo ERROR: Invalid format in mask: "%format%" & exit /B 2
)
)
if defined password (
set /P "=*" < NUL
) else (
set /P "=%key%" < NUL
)
set "input=%input%%key%"
:nextFormat
set /A i+=1
:checkFormat
set "format=!mask:~%i%,1!"
if "%format%" equ "" (
if /I "%switch%" equ "/A" goto endRead
if /I "%switch%" equ "/M" goto endRead
goto nextKey
)
if "!show:%format%=!" neq "%show%" (
if "!key!" equ "!BS!" (
if "%format%" neq " " (
set /P "=%format%!BS!!BS!Û!BS!" < NUL
) else (
set /P "=!SP!!BS!!BS!Û!BS!" < NUL
)
set "input=%input:~0,-1%"
set /A i-=1
if !i! equ 0 set key=0
goto checkFormat
) else (
if "%format%" neq " " (
set /P "=%format%" < NUL
) else (
set /P "=!SP!" < NUL
)
set "input=%input%%format%"
goto nextFormat
)
)
if "%input:~-1%!key!" equ " !BS!" (
set /P "=Û!BS!!BS!" < NUL
set "input=%input:~0,-1%"
set /A i-=1
goto checkFormat
)
goto nextKey
:endRead
echo/
endlocal & set "%var%=%input%"
echo %INPUT%
pause
exit /B
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to make a text-based game using Batch, and this part used to work but it suddenly doesn't. As soon as I press enter after typing a name, the program terminates suddenly and displays the error: . was unexpected at this time
I'm pretty sure this shouldn't even happen, and I know the error has to be somewhere in the following code:
`
:CFGNAME
cls & title N.A.M.E & color 0d
echo --------------------------------------
echo State your identity.
echo --------------------------------------
echo.
echo You need to specify things like your
echo name and gender.
echo.
echo.
echo.
echo Gender: %gender%
echo.
echo Enter a name. It may be up to sixteen
echo characters long, and can contain any
echo letter, and only letters. Most other
echo glyphs will crash the game.
echo.
echo.
echo -Enter a
set /p tmpName=- name:
echo %tmpName%> "data\temp\~playername.tmp"
for %%? in ("data\temp\~playername.tmp") do ( set /A nameLength=%%~z? - 2 )
del "data\temp\~playername.tmp"
set ucdName=%tmpName%
set ucdName=%ucdName:A= %
set ucdName=%ucdName:a= %
set ucdName=%ucdName:B= %
set ucdName=%ucdName:b= %
set ucdName=%ucdName:C= %
set ucdName=%ucdName:c= %
set ucdName=%ucdName:D= %
set ucdName=%ucdName:d= %
set ucdName=%ucdName:E= %
set ucdName=%ucdName:e= %
set ucdName=%ucdName:F= %
set ucdName=%ucdName:f= %
set ucdName=%ucdName:G= %
set ucdName=%ucdName:g= %
set ucdName=%ucdName:H= %
set ucdName=%ucdName:h= %
set ucdName=%ucdName:I= %
set ucdName=%ucdName:i= %
set ucdName=%ucdName:J= %
set ucdName=%ucdName:j= %
set ucdName=%ucdName:K= %
set ucdName=%ucdName:k= %
set ucdName=%ucdName:L= %
set ucdName=%ucdName:l= %
set ucdName=%ucdName:M= %
set ucdName=%ucdName:m= %
set ucdName=%ucdName:N= %
set ucdName=%ucdName:n= %
set ucdName=%ucdName:O= %
set ucdName=%ucdName:o= %
set ucdName=%ucdName:P= %
set ucdName=%ucdName:p= %
set ucdName=%ucdName:Q= %
set ucdName=%ucdName:q= %
set ucdName=%ucdName:R= %
set ucdName=%ucdName:r= %
set ucdName=%ucdName:S= %
set ucdName=%ucdName:s= %
set ucdName=%ucdName:T= %
set ucdName=%ucdName:t= %
set ucdName=%ucdName:U= %
set ucdName=%ucdName:u= %
set ucdName=%ucdName:V= %
set ucdName=%ucdName:v= %
set ucdName=%ucdName:W= %
set ucdName=%ucdName:w= %
set ucdName=%ucdName:X= %
set ucdName=%ucdName:x= %
set ucdName=%ucdName:Y= %
set ucdName=%ucdName:y= %
set ucdName=%ucdName:Z= %
set ucdName=%ucdName:z= %
set "ucdName=!ucdName: =!"
echo %ucdName%x> "data\temp\~checknamecontents.tmp"
for %%? in ("data\temp\~checknamecontents.tmp") do ( set /A invalidChars=%%~z? - 2 )
set /a invalidChars-=1
del "data\temp\~checknamecontents.tmp"
if %invalidChars% gtr 0 (
cls & title I.N.V.A.L.I.D & color 0c
echo.
echo Your name
echo must only contain letters!
echo.
echo The name you entered cannot be
echo used because if your name was
echo not fully alphabetical, pass-
echo words generated using that name
echo would be improperly generated.
echo It has %invalidChars%
echo invalid character(s).
echo.
echo Press any key to retry...
echo.
pause > nul
goto CFGNAME
)
:CHKNAMELENGTH
if %nameLength% gtr 16 (
cls & title I.N.V.A.L.I.D & color 0c
echo.
echo Your name must be up to 16
echo characters in length!
echo.
echo The name you entered cannot be
echo used because %nameLength% is
echo more than 16.
echo.
echo.
echo.
echo.
echo.
echo Press any key to retry...
echo.
pause > nul
goto CFGNAME
) else (
if %nameLength% lss 3 (
cls & title I.N.V.A.L.I.D & color 0c
echo.
echo Your name must be at least 3
echo characters in length!
echo.
echo The name you entered cannot be
echo used because %nameLength% is
echo less than 3.
echo.
echo.
echo.
echo.
echo.
echo Press any key to retry...
echo.
pause > nul
goto CFGNAME
) else (
set name=%tmpName%
goto CFGID
)
)
:CFGID
set IDEasterEgg=*
if /i "%tmpName%"=="Undyne" (
set IDEasterEgg=* Ngaaah!
)
if /i "%tmpName%"=="Frisk" (
set IDEasterEgg=* -_-
)
if /i "%tmpName%"=="Mario" (
set IDEasterEgg=* Lets-a-go!
)
if /i "%tmpName%"=="Waluigi" (
set IDEasterEgg=Waaa!
)
if /i "%tmpName%"=="Link" (
set IDEasterEgg=* Nice job, "princess."
)
if /i "%tmpName%"=="Navi" (
set IDEasterEgg=* Hey! Listen!
)
if /i "%tmpName%"=="Yoda" (
set IDEasterEgg=* Backwards I talk. Hm.
)
if /i "%tmpName%"=="Darth Vader" (
set IDEasterEgg=* No. I am your father.
)
if /i "%tmpName%"=="Mabbel" (
set IDEasterEgg=* GRAPPLING HOOK!!!
)
if /i "%tmpName%"=="Stanley" (
set IDEasterEgg=* Illegal pyrotechnics, anyone?
)
if /i "%tmpName%"=="Steve" (
set IDEasterEgg=* It's. A cow.
)
if /i "%tmpName%"=="Notch" (
set IDEasterEgg=* <3
)
if /i "%tmpName%"=="Caillou" (
set IDEasterEgg=* But Mommy!
)
if /i "%tmpName%"=="Rosie" (
set IDEasterEgg=* STUPID! STUPID! :D
)
if /i "%tmpName%"=="Testificate Man" (
set IDEasterEgg=* How inconsiderate!!!
)
if /i "%tmpName%"=="Dr Inconsiderate" (
set IDEasterEgg=* Slightly less than average!
)
if /i "%tmpName%"=="Shaggy" (
set IDEasterEgg=* Zoinks!
)
if /i "%tmpName%"=="Scooby-Doo" (
set IDEasterEgg=* Rello, rorld!!
)
if /i "%tmpName%"=="Santa Claus" (
set IDEasterEgg=* Ho ho ho!
)
if /i "%tmpName%"=="Easter Bunny" (
set IDEasterEgg=* You've found an Easter egg.
)
if /i "%tmpName%"=="Ed" (
set IDEasterEgg=* Head: Looks like flat pear.
)
if /i "%tmpName%"=="Edd" (
set IDEasterEgg=* Headwear: Very mysterious...
)
if /i "%tmpName%"=="Eddy" (
set IDEasterEgg=* Smile: Freakishly huge.
)
if /i "%tmpName%"=="Pacman" or "%tmpName%"=="Pac Man" (
set IDEasterEgg=* Wafers: A LOT
)
if /i "%tmpName%"=="Ms Pacman" or "%tmpName%"=="Ms Pac Man" (
set IDEasterEgg=* Children: Jr. Pac-Man
)
if /i "%tmpName%"=="Blinky" (
set IDEasterEgg=* Personality: Leader
)
if /i "%tmpName%"=="Clyde" (
set IDEasterEgg=* Personality: Teasing
)
if /i "%tmpName%"=="Inky" (
set IDEasterEgg=* Personality: Shy
)
if /i "%tmpName%"=="Pinky" (
set IDEasterEgg=* Personality: Energetic
)
if /i "%tmpName%"=="MatPat" (
set IDEasterEgg=* But that's just a theory.
)
:CFGID
cls & title Y.O.U S.U.R.E? & color 02
echo --------------------------------------
echo Is this ID okay with you?
echo ----------------------------------
echo This will be your character for the
echo rest of the game. Are you sure you
echo have everything exactly how you
echo want it? If not, you can go back
echo and edit your info all you like.
echo Anything but Y will be interpreted
echo as a no!
echo --------------------------------------
echo.
echo * Name: %name%
echo.
echo * Gender: %gender%
echo.
echo %IDEasterEgg%
echo.
echo __ __ __ __ __ __ ^|
echo _/ \__/ \__/ \__/ \__/ \__/ \__/
echo.
set /p confirmCharacter=(Y, N):
`
If anybody can figure out what's causing the problem, I'd really appreciate it.
The line echo invalid character(s). is the problem. The ) closes your code block, resulting in . to be interpreted as a command. Escape it with a caret:
echo invalid character(s^).
I was wondering...
I have a program, and I want to charge money for it.
it runs on Windows, and is written mostly in VB and Batch-files...
how can I force the user to buy a product key for it, and activate it to use the Paid Version?
Thanks in advance!
~ #Cascading-style
This just a little example showing you that you can limit the number of execution of your program , so if the maximum of number of execution is reached the program will Auto delete by him self
#echo off
Setlocal enabledelayedexpansion
Title Count the number of times my BATCH file is run
Mode Con Cols=70 lines=7 & color 0E
Set /a MaxExecution=3
set /a count=1
set "FileCount=%tmp%\%~n0.dll"
If Not exist "%FileCount%" (
echo !count! > "%FileCount%"
) else (
For /F "delims= " %%a in ('Type "%FileCount%"') Do (
set /a count=!count! + %%a
echo !count! > "%FileCount%"
)
)
echo.
echo This Program is running for "!count!" time(s)
Call :SelfDelete
pause>nul & Exit /b
::**************************************************************
:SelfDelete
echo.
If !count! GTR !MaxExecution! (
Color 0C
echo The maximum execution of this "%~nx0" is set to "!MaxExecution!"
echo and it is reached & Timeout /T 5 /Nobreak>nul & Del %~f0
) else (
echo The counting is "!count!" and the max is set to "!MaxExecution!"
)
Goto :EOF
::**************************************************************
I cannot find my bug, after set /p sum=give nr %amount%: it closes.
Does anybody have an Idea why ?
thanks anyway;-)
::Made By QluPreX 29/01/2015
#echo off
cls
color a
:SET_NUM
set /p tot=how many numbers:
cls
set amount=1
set sum_tot=0
echo %tot%?
set /p y_or_n=is that correct (y/n) ? :
if %y_or_n%==y (
cls
goto:GIVE_NUM
) ELSE (
cls
goto:SET_NUM
)
:GIVE_NUM
set /p sum=give nr %amount%:
set /a sum_tot=%sum_tot%+%sum%
set /a amount=%amount%+1
if /I %amount%==%tot%(
goto:DISPLAY
)ELSE(
goto:GIVE_NUM
)
:DISPLAY
echo total is %sum_tot%
pause
No idea what you mean by set /p sum=give nr %amount%:
but
)ELSE(
Must be
) ELSE (
(spaces required)
equally,
if /I %amount%==%tot%(
must be
if /I %amount%==%tot% (
I have a batch file that takes an input file (in this case the file is a flat text file comprised of a file listing from a specified set of Windows XP system directories).
Then through a combination of a for loop to iterate through each file listed in the text file), setting a variable, using several call commands (in this case 9), and the find command to search the text file for files that appear in the output of other flat files.
The problem I am running into is that csrss.exe is using quite a bit of CPU processing. In reading some other articles it seems that csrss has a relationship with command line processing.
What I want to know is if there is a better way to do this that will:
Reduce overall script time.
Reduce CPU load.
Below is a sample of the script:
:: ------------------------------------------------------
:: Running Multiple Commands
:: ------------------------------------------------------
for /f "delims=?" %%A in (dir-selected_tmp.txt) do (
set filepath=%%A
call :filepathparse
call :md5hashchk
call :versionchk
call :densitychk
call :processchk
call :mutexchk
call :networkchk
call :injectedchk
call :persistservicechk
call :servicedllchk
call :persistrunchk
call :persistothchk
call :unsigneddllchk
call :filesysag
)
goto :comparison
:: ####################################################################
:filepathparse
for %%B in ("%filepath%") do (
set filename=%%~nxB
)
goto :eof
:: ####################################################################
:md5hashchk
for /f "delims= " %%b in ('md5deep.exe "%filepath%"') do set hashvalue=%%b
goto :eof
:: ####################################################################
:versionchk
for /f "delims= " %%e in ('sigcheck.exe /accepteula -q -n "%filepath%"') do set versionvalue=%%e
goto :eof
:: ####################################################################
:densitychk
for /f "delims= " %%d in ('densityscout.exe -p 0.1 "%filepath%"') do set densityvalue=%%d
goto :eof
:: ####################################################################
:processchk
find.exe /I "%filepath%" %temp_outpath%\wmic-processes.txt > nul 2>&1 && goto processexist
set isprocess=NoActiveProc
goto :eof
:processexist
set isprocess=ActiveProc
goto :eof
:: ####################################################################
:mutexchk
if "%startup_chk%"=="-b" (
goto :mutexbl
)
find.exe /I "%filepath%" %temp_outpath%\filesystem-handles_compared.txt > nul 2>&1 && goto mutexexist
set ismutex=NoNewActiveMutex
goto :eof
:mutexexist
set ismutex=NewActiveMutex
goto :eof
:mutexbl
find.exe /I "%filepath%" %parsed_outpath%\filesystem-handles.txt > nul 2>&1 && goto mutexexist
set ismutex=NoNewActiveMutex
goto :eof
:mutexexist
set ismutex=NewActiveMutex
goto :eof
:: ####################################################################
:networkchk
find.exe /I "%filename%" %temp_outpath%\tcpvcon_tmp.txt > nul 2>&1 && goto networkexist
set isnetwork=NoActiveNetwork
goto :eof
:networkexist
set isnetwork=ActiveNetwork
goto :eof
:: ####################################################################
:injectedchk
find.exe /I "%filepath%" %temp_outpath%\injecteddll_tmp.txt > nul 2>&1 && goto injectedexist
set isinjected=NoActiveInject
goto :eof
:injectedexist
set isinjected=ActiveInject
goto :eof
:: ####################################################################
:persistservicechk
find.exe /I "%filepath%" %temp_outpath%\autoruns-services_tmp.txt > nul 2>&1 && goto serviceexist
set isservice=NoInstalledService
goto :eof
:serviceexist
set isservice=InstalledService
goto :eof
:: ####################################################################
:servicedllchk
find.exe /I "%filepath%" %temp_outpath%\registry_hklm_installed_service_dlls_final.txt > nul 2>&1 && goto servicedllexist
set isservicedll=NoInstalledServiceDLL
goto :eof
:servicedllexist
set isservicedll=InstalledServiceDLL
goto :eof
:: ####################################################################
:persistrunchk
find.exe /I "%filepath%" %temp_outpath%\autoruns-run_tmp.txt > nul 2>&1 && goto runpersistexist
set isrunpersist=NoRunPersist
goto :eof
:runpersistexist
set isrunpersist=RunPersist
goto :eof
:: ####################################################################
:persistothchk
find.exe /I "%filepath%" %temp_outpath%\autoruns-oth_tmp5.txt > nul 2>&1 && goto persistothexist
set isothpersist=NoOtherPersist
goto :eof
:persistothexist
set ispersist=OtherPersist
goto :eof
:: ####################################################################
:unsigneddllchk
find.exe /I "%filepath%" %temp_outpath%\listdlls_temp2.txt > nul 2>&1 && goto unsigneddllexist
set isunsigneddll=NoUnSignedProcDLL
goto :eof
:unsigneddllexist
set isunsigneddll=UnSignedProcDLL
goto :eof
:: ####################################################################
:filesysag
:: Compiling Into Syslog Format
echo %datestamp%^|%currtime%^|%computername%^|%currip%^|%username%^|%lastlogintime%^|"%filepath%"^|%hashvalue%^|%versionvalue%^|%densityvalue%^|%isprocess%^|%ismutex%^|%isnetwork%^|%isinjected%^|%isservice%^|%isservicedll%^|%isrunpersist%^|%isothpersist%^|%isunsigneddll% >> %syslog_outpath%\%computername%-syslog.txt
:: Compiling Into Parsed Format
echo "%filepath%"^|%hashvalue%^|%versionvalue%^|%densityvalue%^|%isprocess%^|%ismutex%^|%isnetwork%^|%isinjected%^|%isservice%^|%isservicedll%^|%isrunpersist%^|%isothpersist%^|%isunsigneddll% >> %parsed_outpath%\%computername%-filesystem.txt
goto :eof
Sadly, your reluctance to provide further details means we are severely retricted on the amount of help we can offer.
I'd recommend:
First, build a list of the filepaths yu are interested in
(for /f "delims=?" %%A in (dir-selected_tmp.txt) do echo %%A )>paths_of_interest.txt
Then build temporary files containing a subset of the log data
findstr /I /g:paths_of_interest.txt %temp_outpath%\processes.txt >"%temp%\processes.x.txt"
Then re-process according to your original scheme, instead using paths_of_interest.txt and "%temp%\processes.x.txt"
This should reduce the amount of repetition, especially if you have long files.
:: ------------------------------------------------------
:: Running Multiple Commands
:: ------------------------------------------------------
:: Pre-processing
SET /a step=1000
SET /a dirstart=0
SET "dirskip="
:mainloop
SET /a dirsleft=0
SETLOCAL enabledelayedexpansion
(
for /f "%dirskip%delims=?" %%A in (dir-selected_tmp.txt) do (
SET /a dirsleft+=1
IF !dirsleft! leq %step% ECHO %%A
)
)>temp_dirs.txt
endlocal&SET /a dirsleft=%dirsleft%
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\wmic-processes.txt" >temp_filepathparse.txt
if "%startup_chk%"=="-b" (
FINDSTR /i /l /g:temp_dirs.txt "%parsed_outpath%\filesystem-handles.txt" >temp_mutexchk.txt
) ELSE (
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\filesystem-handles_compared.txt" >temp_mutexchk.txt
)
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\tcpvcon_tmp.txt" >temp_networkchk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\injecteddll_tmp.txt" >temp_injectedchk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\autoruns-services_tmp.txt" >temp_persistservicechk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\registry_hklm_installed_service_dlls_final.txt" >temp_servicedllchk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\autoruns-run_tmp.txt" >temp_persistrunchk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\autoruns-oth_tmp5.txt" >temp_persistothchk.txt
FINDSTR /i /l /g:temp_dirs.txt "%temp_outpath%\listdlls_temp2.txt" >temp_unsigneddllchk.txt
for /f "delims=" %%A in (temp_dirs.txt) do (
set "filepath=%%A"
call :filepathparse
....
call :filesysag
)
SET /a dirstart=%dirstart%+%step%
SET /a dirsleft=%dirsleft%-%step%
IF dirsleft gtr 0 SET dirskip=SKIP=%dirstart%&GOTO mainloop
goto :comparison
Then simply replace the filename in each of your routines :processchk to :unsigneddllchk with the corresponding temp_whatever.txt file created in the pre-processing. The switch on mutex is already done in the pre-processing.
This should reduce the searching done by the find command and hence the overall run time by selecting only those lines containing the target strings into the temp_* files created.
[Edit in response to further information provided]
Note the preprocessing block before the first findstr has been changed and that there is now a post-processing block between call :filesysag ) and goto :comparison
The object here is to reduce the size of the temp_dirs.txt file. I've arbitrarily chosen 1,000 (the size of step) but have no real idea of how big step should be. The larger it is, the quicker the process will be, but if it's too large, temp_dirs.txt will be too big for findstr to handle.
Note the use of the parsing trick on the line endlocal&SET /a dirsleft=%dirsleft% which uses the parsing system to move the modified value of dirsleft out of the setlocal/endlocal block.