Is there a way to write a .bat file which sends all my inputs to a program running in background ?
Something like this ,
c:\start.bat
Opens a new prompt ,
But whatever I type in new prompt should go to the default program running in the background (Don't know where to specify the default program , I don't want to show the program name each time I pass the arguments). I want to use something like this line ,
<CUSTOM_PROMPT>"select data from tablex" , the string should go the "programX.bat"
instead of
<CUSTOM_PROMPT>programX.bat "select data from tablex"
I am afraid your question is not clear; there are many details that needs clarification. However, the Batch file below may give a starting point of discussion for both of us:
#echo off
setlocal
if "%~1" equ "goto" goto %2
cls
echo I am the user-interface program
echo Enter "exit" (with no quotes) to end
echo/
"%~F0" goto getInput | "%~F0" goto background > background.txt
echo/
echo The user-interface program ends
echo/
echo This is the input captured by background program:
echo/
type background.txt
goto :EOF
:getInput
set /P "input=<CUSTOM_PROMPT>: " > CON
echo %input%
if /I "%input%" neq "exit" goto getInput
goto :EOF
:background
set /P input=
if /I "%input%" equ "exit" goto :EOF
echo Input received at %time%:
echo %input%
echo/
goto background
Related
Below, I wrote some code. It detects if a Micro-SD card is inserted into the computer and if so, it will ask to enter your pin. After you enter the pin, it will look through the card for a text file that contains a list of pins.
:start
cls
echo.
echo.
if exist E:\ (
goto enterPin
) else (
echo INSERT YOUR CARD
)
timeout 1 >nul
goto start
:enterPin
echo Enter Account Pin: %chip%
set /p pin=": "
:: Finding the specified pin
findstr /m "%pin%" E:\Chip\CardInfo.txt >Nul
if %errorlevel%==0 (
echo Pin "%pin%" is valid
timeout 1 >nul
goto account
)
if %errorlevel%==1 (
echo Pin "%pin%" is invalid
pause
goto start
)
:account
cls
:: Finds the name of the account owner and continues
setlocal enableextensions disabledelayedexpansion
for /F "tokens=2 delims=/" %%a in ('findstr /I "%pin%/" E:\Chip\CardInfo.txt') do set "user=%%a"
for /F "tokens=3 delims=/" %%b in ('findstr /I "%pin%/%user%/" E:\Chip\CardInfo.txt') do set "balance=%%b"
echo.
echo.
echo Welcome, %user%.
echo.
echo ACCOUNT BALANCE: $%balance%
echo.
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
choice /c 1234 >nul
if %ERRORLEVEL% EQU 1 goto deposit
if %ERRORLEVEL% EQU 2 goto withdraw
if %ERRORLEVEL% EQU 3 exit
if %ERRORLEVEL% EQU 4 goto account
:deposit
echo.
echo.
set /p add="Money to Deposit: "
set /a moneytoadd=%balance%+%add%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /f E:\Chip\CardInfo.txt /o -
goto account
:withdraw
echo.
echo.
set /p sub="Money to Withdraw: "
set /a moneytosub=%balance%-%sub%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /f
E:\Chip\CardInfo.txt /o -
goto account
endlocal
Here's when the issue comes in. A pin consists of 4 numeric characters (ex. 1234), but if there's two pins with the same characters (ex. 1234, 6543), it will say the pin is valid. So for example, if I type 4, it will just look for just the number 4 in the file. And will say the pin is valid. Even though, just the number 4 is not an existing pin. My guess is that it's a flaw with "findstr". But I'm not sure.
Contents of "CardInfo.txt":
1234/Test User/1000
6543/Another Test User/2000
use REGEX (using <StartOfLine><PIN></>):
findstr /m "^%pin%/" E:\Chip\CardInfo.txt >Nul
where ^ is "Start of Line".
Here is what exactly does what you want:
#echo off
::add your path below
for /f %%a in (file.txt) do (
call :funch %%a
)
:funch
set input=%1
set "modifiedinput=%input:~0,4%"
set /p pin=Enter Account Pin:
if %modifiedinput% equ %pin% ( goto authentication_passed) else ( goto authentication_failed)
:authentication_passed
echo auth passed
rem your code
pause >nul
exit
:authentication_failed
echo auth failed
goto funch
it will read the input from file and then extract first four characters which in your case is the pin.
I rewrote the entire batch file to be more fail safe on execution:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem endlocal is executed implicitly by cmd.exe on exiting batch file processing.
:Begin
cls
echo\
echo\
if exist E:\ goto enterPin
echo INSERT YOUR CARD
%SystemRoot%\System32\timeout.exe /T 1 >nul
goto Begin
:enterPin
set "pin="
set /p pin="Enter account pin for %chip%: "
if not defined pin goto enterPin
set "pin=%pin:"=%"
if not defined pin goto enterPin
for /F delims^=01234567890^ eol^= %%I in ("%pin%") do goto enterPin
rem Finding the specified pin.
%SystemRoot%\System32\findstr.exe /B /L /M /C:"%pin%/" E:\Chip\CardInfo.txt >Nul
if errorlevel 1 (
echo Pin "%pin%" is invalid.
pause
goto Begin
)
echo Pin "%pin%" is valid.
%SystemRoot%\System32\timeout.exe /T 1 >nul
:account
cls
rem Finds the name of the account owner and continues
for /F "tokens=2,3 delims=/" %%I in ('%SystemRoot%\System32\findstr.exe /B /L /C:"%pin%/" E:\Chip\CardInfo.txt') do set "user=%%I" & set "balance=%%J"
echo/
echo/
echo Welcome, %user%.
echo/
echo ACCOUNT BALANCE: $%balance%
echo/
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
%SystemRoot%\System32\choice.exe /c 1234 >nul
if not errorlevel 1 goto account
if errorlevel 4 goto account
if errorlevel 3 exit /B
if errorlevel 2 goto withdraw
:deposit
echo/
echo/
set "add="
set /P "add=Money to deposit: "
set /A moneytoadd=balance + add
call "%~dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /L /f E:\Chip\CardInfo.txt /o -
goto account
:withdraw
echo/
echo/
set "sub="
set /P "sub=Money to withdraw: "
set /A moneytosub=balance - sub
call "%dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /L /f E:\Chip\CardInfo.txt /o -
goto account
Issues fixed with this code:
There is the command START. For that reason it is not advisable to use the string start as label although it is possible.
It is advisable to avoid an IF (...) ELSE (...) condition if a simple IF condition with GOTO can be used too.
The usage of full qualified file names wherever possible avoids a batch file not running as expected on environment variables PATH (too often) or PATHEXT (rarely) are corrupted on the userĀ“s machine.
A user has the freedom to enter on a prompt done with set /P really anything from nothing to something resulting in further processing in a syntax error with an immediate exit of batch file execution on code not being prepared for any user input. For that reason the first set /P prompt is improved and validates if the user entered a string consisting only of digits.
The usage of FINDSTR is done with additional options to find the pin only at beginning of a line case-sensitive with a literal search and the next character must be a slash character.
The recommended syntax for ERRORLEVEL evaluation is used in the code.
The arithmetic expressions are written using the recommended syntax to work even if the user enters nothing or a string which cannot be converted to an integer number at all.
The command EXIT is used with option /B to just exit the processing of the batch file and not the entire command process.
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.
call /?
choice /?
cls /?
echo /?
findstr /?
for /?
goto /?
if /?
pause /?
rem /?
set /?
setlocal /?
timeout /?
Useful pages regarding to the improvements on code:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Syntax error in one of two almost-identical batch scripts: ")" cannot be processed syntactically here
DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/
Single line with multiple commands using Windows batch file
Safe number comparison in Windows batch file
In Windows batch, I'm asking the user whether he wants to use the program's internal default or wants to set his own parameters, but no matter what the user sets as an answer, the program always jumps straight to the main routine using the internal defaults. This is my code:
#echo off
setlocal EnableDelayedExpansion
choice /C:yn /M "Use internal defaults? "
if errorlevel==1 goto yes
if errorlevel==2 goto no
rem use default
:yes
set "MYNUMBER=5"
goto run
rem let user define another number
:no
set /P MYNUMBER="Please set a number: "
goto run
rem main routine
:run
echo %MYNUMBER%
pause
What am I missing?
And since we're at it: how can I force the program to wait for the user to hit "Enter" after typing his choice? Right now, it starts directly after typing "y" or "n".
Thanks to the commentators, that helped a lot! Now its working like this:
#echo off
setlocal EnableDelayedExpansion
:ask
set /P USER_CHOICE="Use internal defaults? (Y/N) "
if /i "%USER_CHOICE%"=="y" (
goto yes
) else (
if /i "%USER_CHOICE%"=="n" (
goto no
) else (
echo "Wrong input! Please choose Y or N!"
goto ask
)
)
rem use default
:yes
set "MYNUMBER=5"
goto run
rem let user define another number
:no
set /P MYNUMBER="Please set a number: "
goto run
rem main routine
:run
echo %MYNUMBER%
pause
I want to make a bat file that list all of the files in a specific directory, and add numbers at the beginning of the every one of the listed items. This numbers need to be a selectable options.
Example:
I have a folder with 5 files in it, aaa.exe, bbb.exe, ccc.exe, ddd.exe, eee.exe. When i run bat file i need to see
aaa.exe
bbb.exe
ccc.exe
ddd.exe
eee.exe
So now if i wana run 5-th exe i need to press 5, than press enter and that 5th exe will now start.
I allredy find how to list all of the items in folder with this code
REM -start "c:\windows\system32" notepad.exe
for /r %%i in (*) do echo %%i
pause
exit
but i can't figure out how to add numbers in front of the text and make that numbers to be a selectable options.
Edit---
Now im getting
ERROR: Duplicate choices are not allowed. running '""' is not
recognized as an internal or external command, operable program or
batch file.
when i'm trying to run this loop for a second time.
This is code that i wrote:
#ECHO OFF
setlocal enabledelayedexpansion
REM ---Prompt part
:choise
SET /P AREYOUSURE=Install programs (Y/[N])?
IF /I "%AREYOUSURE%" EQU "Y" GOTO :chooseInstall
IF /I "%AREYOUSURE%" EQU "N" GOTO :nope
REM --Cheking for Y or N
GOTO :choise
:nope
echo "Ok. Have a nice daty / night"
pause
exit
:chooseInstall
echo Wich program do you wana install ?
echo.
echo 1. 7Zip
echo 2. CPU Z
echo.
SET /P AREYOUSURE=Choosing:
IF /I "%AREYOUSURE%" EQU "1" set "pathToSoft=C:\Users\usr\Desktop\hello"
IF /I "%AREYOUSURE%" EQU "2" set "pathToSoft=C:\Users\usr\Desktop\bye"
echo.
echo.
echo %pathToSoft%
echo.
echo.
REM ---Installs
echo "Wich file to install"
cd %pathToSoft%
echo.
echo.
REM --Loops that scan files
set /A counter=0
for /R %%i in (*) do (
if not "%%~nxi" == "%~nx0" (
set /A counter+=1
echo !counter!: %%~nxi
set exe[!counter!]=%%i
set choice=!choice!!counter!
)
)
if %counter% LSS 10 (
choice /C %choice% /M "Choose: "
set EXENUM=!ERRORLEVEL!
) else set /P EXENUM="enter exe number: "
set EXECUTABLE=!exe[%EXENUM%]!
echo running %EXECUTABLE%
call "%EXECUTABLE%"
echo.
echo.
echo.
:installmore
SET /P INSTALLMORE=Do you wana install somthing else (Y/[N])?
IF /I "%INSTALLMORE%" EQU "Y" GOTO :chooseInstall
IF /I "%INSTALLMORE%" EQU "N" GOTO :nope
count the executables and associate them with the counter, creating kind of "array" variables (filter out the current batch script)
build the choice list at the same time
after the loop, use choice if no more than 9 choices, else use a classical interactive set
retrieve the user selection and call the executable/batch file
(you have to enable delayedexpansion to be able to use % and ! env. var separators & instant evaluation within the loop)
can be done like this:
#echo off
setlocal enabledelayedexpansion
set /A counter=0
set choice=
for /R %%i in (*) do (
if not "%%~nxi" == "%~nx0" (
set /A counter+=1
echo !counter!: %%~nxi
set exe[!counter!]=%%i
set choice=!choice!!counter!
)
)
if %counter% LSS 10 (
choice /C %choice% /M "type exe number"
set EXENUM=!ERRORLEVEL!
) else set /P EXENUM="enter exe number: "
set EXECUTABLE=!exe[%EXENUM%]!
echo running %EXECUTABLE%
call "%EXECUTABLE%"
I'm trying to make a username change option for the settings in one of my batch file programs, but it keeps displaying a message like "set was unexpected at this time" which is weird, because my code seems right. It happens after entering a value for "cuser". None of the values I'm entering for input are null, since I've pre-declared the values at the beginning of the program to make it so I didn't have any null-value errors.
:uch
cls
echo.
echo Are you sure you want to change your username?
echo.
echo [Y/N]
echo.
set /p input=
if %input% EQU n goto set
if %input% NEQ y goto uch
:ucy
cls
echo.
echo Enter your current username
echo.
set /p cuser=
if %cuser% NEQ %username1% (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
echo.
pause>null
goto :ucy
)
if %cuser% EQU %username1% (
echo Please enter new username.
echo.
set /p nuser=
echo Please enter again.
echo.
set /p nuser2=
if %nuser2% EQU %nuser% set username1=%nuser%
if %nuser2% EQU %nuser% goto ga1
if %nuser2% NEQ %nuser% (
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>null
goto ucy
)
goto ucy
You are trying to set value of variable inside if block without delayed expansion and the if is parsed with wrong syntax.And you have one unclosed bracket...
:uch
cls
echo.
echo Are you sure you want to change your username?
echo.
echo [Y/N]
echo.
set /p input=
if %input% EQU n goto set
if %input% NEQ y goto uch
:ucy
cls
echo.
echo Enter your current username
echo.
set /p cuser=
if %cuser% NEQ %username1% (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
echo.
pause>null
goto :ucy
)
setlocal enableDelayedExpansion
if %cuser% EQU %username1% (
echo Please enter new username.
echo.
set /p nuser=
echo Please enter again.
echo.
set /p nuser2=
if !nuser2! EQU !nuser! set username1=!nuser!
if !nuser2! EQU !nuser! goto ga1
if !nuser2! NEQ !nuser! (
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>null
goto ucy
)
goto ucy
You are not using the proper syntax for the if command. When comparing strings, use
if "%var1%"=="%var2%" to compare. EQL NEQ etc. are for numeric comparison.
You DO NOT need to have multiple if statements (one for yes and one for no) because, you can assume that if they didn't say yes then they meant to say no. Here is an improved script for you, one that doesn't need delayed expansion in order to work. Hope this helps.
:uch
cls
echo.
echo Are you sure you want to change your username?
set /p input=[Y/N]
if not "%input%"=="y" (goto ga1)
::THEY WANT TO CHANGE THEIR USERNAME
cls
echo.
set /p cuser=Enter your current username ^>
if not "%cuser%"=="%username1%" (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
pause>NUL
goto :uch
)
::THE USERNAME MATCHES
echo.
set /p nuser=Please enter new username. ^>
echo.
set /p nuser2=Please enter again. ^>
if "%nuser2%"=="%nuser%" (set username1=%nuser% && goto ga1)
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>NUL
goto uch
:ga1
:://DO SOME OTHER STUFF HERE AFTER THEY CHANGED THEIR NAME OR OPTED NOT TO.
I have one Windows 10 command prompt running and awaiting input, and I wish to automate continuous and live input with a second command prompt. I have gotten the second command prompt to extract the desired variable, and I wish to send it to the other command prompt that is waiting for input.
The "awaiting input" command prompt must run in real time because it is connected to Plink (not an SSH session so no use of the -m command here) which is connecting to a microcontroller. So it cannot be accomplished (at least I don't think) with function calls.
I see that it can be done in UNIX environments: https://askubuntu.com/questions/496914/write-command-in-one-terminal-see-result-on-other-one
Thanks in advance and please advise,
--A hopeful beginner
Batch code starts 2 piped processes, one for getting keyboard input and writing to a file, and the other reading the data written. Note there isn't a cmd window for each process, but there are two new processes running. You may use cmd /c or start if you need two consoles.
Does it help?
#echo off
set "pipefile=pipefile.txt"
if "%~1" neq "" goto %1
copy nul "%pipefile%" >nul
"%~F0" getInput >>"%pipefile%" | "%~F0" readInput <"%pipefile%"
echo(
echo(Batch end...
ping localhost -n 1 >nul
del /F /Q "%pipefile%" 2>nul
exit/B
:getInput
set "input="
set/P "input="<CON
echo(%input%
if /I "%input%" equ "EXIT" exit
goto:getInput
:readInput
setlocal enableDelayedExpansion
set/P="enter some data [EXIT to exit] "
for /l %%. in () do (
set "input="
set/P "input="
if defined input (
if /I "!input!" equ "EXIT" exit
set/P="enter some data [EXIT to exit] "
)
ping 1.1.1.1 -w 10 -n 1 >nul 2>nul & rem avoid processor load (may be removed)
)
Running two console windows
#echo off
set "pipefile=pipefile.txt"
if "%~1" neq "" goto %1
del /F /Q "%pipefile%" 2>nul
copy nul "%pipefile%" >nul
start "writer" cmd /c ^""%~f0" readInput ^<"%pipefile%" ^"
start "reader" cmd /c ^""%~f0" getInput ^"
echo(
Echo batch end...
ping localhost -n 1 >nul
goto :EOF
:getInput
set "input="
set/P "input=enter some data [EXIT to exit] "
echo(%input%>>"%pipefile%"
if /I "%input%" equ "EXIT" exit
goto:getInput
:readInput
setlocal enableDelayedExpansion
for /l %%. in () do (
set "input="
set /p "input="
if defined input (
if /I "!input!" equ "EXIT" exit
echo(!input!
)
ping 1.1.1.1 -w 10 -n 1 >nul 2>nul & rem avoid processor load (may be removed)
)