Running a batch file which requires inputs directly from folder - windows

I have a batch file which requires 4 command line inputs. When I execute the batch file on the command prompt, it displays help message asking to input 4 values.
When I run this file directly from the folder, it opens cmd and closes immediately.
Is it possible to modify the batch file, so that when I run from folder it will open the cmd and then display the help message.?
Following is a mini version of my problem with 1 command input. The script is for a License file generation
#ECHO OFF
GOTO :continue
:continue
SETLOCAL
IF "%1" == "" GOTO :Help
::Set the Command Line Options
SET ARVERSION=%1
::Create Directory
SET OUT_PATH=%cd%
ECHO Initiating Generation...
if not exist %OUT_PATH% mkdir %OUT_PATH%
::Create License File - Calling 'Subs' will create the output with actual Version
Subs ARVERSION %ARVERSION% Input.txt 1>%OUT_PATH%\License.txt
ECHO Scripts are created # %OUT_PATH%
ECHO Generation Completed...
GOTO :End
:Help
ECHO Starting License File Generation...
ECHO Usage:
ECHO InstallerScriptGen.bat AR_VERSION
ECHO AR_VERSION - Version (3.2 or 4.0 or 4.2)
ECHO Example : InstallerScriptGen.bat 3.2.2
ECHO Please Note that input of incorrect values will result in wrong generation.
:End
ENDLOCAL

"Running directly from the folder" (by which I assume you mean "clicking on the icon from within Windows Explorer") causes Windows Explorer to execute the equivalent of CMD /C <<batchfilename>>. When invoked with /C, CMD exits (and the CMD window closes) as soon as the batch file ends. You can force the window to stay open long enough to read the output by ending the script with either the PAUSE command (which will cause it to wait for the user to press any key), or the TIMEOUT command (which will wait the indicated number of seconds before continuing, without a keypress). See SS64's help for the PAUSE and TIMEOUT commands for more information.

Related

Starting a batch file in a new window from a batch file, and keeping the new window open after completion

EDIT: I will try to make it clearer what I actually want.
I have some very long batch files that I want to run in order and only starting after the previous one had completed.
I am trying to control this with a master batch file
I want them starting each in their own window which remains open after completion to look back later
In numerical order:
1.run main batch file
2.open new cmd window
3.run batch file 1
4.waiting for 1 to finish
5.1 finished, keep window open
6.open another new cmd window
7.run batch2
etc
-- original message --
Hi so I have a windows batch file that needs to run other windows batch files sequentially and wait for them to finish before starting the next one.
Something like:
#echo off
setlocal EnableDelayedExpansion
SET RUN="C:first.bat"
start /wait cmd /c %RUN%
SET RUN="C:second.bat"
start /wait cmd /c %RUN%
where first and second for example just echo something like:
#echo off
echo 1st
exit /b 0
When I run this it starts the first script in a new window and keeps the window open after completing like I want, but to progress to the second script I have to close the new cmd window.
How can I make the main batch script start the second.bat without closing the first.bat cmd window?
Thanks
It is a very unusual requirement that
other batch files should not be processed by the cmd.exe instance processing the main batch file, but by other instances of cmd.exe just to have their outputs in a different console window and
keep each other command process running after finishing the processing of the batch file to be able to view their outputs in their console windows and
wait with further processing of main batch file until processing of a batch file finished by the started separate command process, but do not wait for termination of the started other command processes.
The Windows command processor cmd.exe is not designed for a serialized multi-processing of batch files with multiple instances of itself which finally should keep running.
However, here are three batch files which demonstrate that this is possible with one disadvantage explained later.
Main.bat
#echo off & goto Main
:WaitForBatch
start "Run %~nx1" %ComSpec% /D /S /K "(%ComSpec% /D /C "%~1") & title Finished %~n1"
echo Waiting for finished execution of "%~nx1" ...
:CheckBatchRun
%WaitCommand% >nul
%SystemRoot%\System32\tasklist.exe /NH /FI "IMAGENAME eq cmd.exe" /V | %SystemRoot%\System32\find.exe /I "%~nx1" >nul
if errorlevel 1 goto :EOF
goto CheckBatchRun
:Main
setlocal EnableExtensions DisableDelayedExpansion
title Run %~nx0
if exist %SystemRoot%\System32\timeout.exe (
set "WaitCommand=%SystemRoot%\System32\timeout.exe /T 1"
) else (
set "WaitCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
)
call :WaitForBatch "%~dp0First.bat"
call :WaitForBatch "%~dp0Second.bat"
title Finished %~n0
pause
endlocal
First.bat
#echo off
dir %SystemRoot% /B /S
Second.bat
#echo off
dir %SystemRoot%\*.exe
echo/
pause
Main.bat is coded in a manner expecting First.bat and Second.bat in the same directory as Main.bat, but the other batch files can be also in different directories. The current directory on execution of the three batch files can be any directory.
Main.bat first sets up the execution environment for itself which is:
command echo mode turned off and
command extensions enabled and
delayed expansion disabled.
The window title of the console window of cmd.exe processing Main.bat is modified to show Run Main.bat at beginning.
Next is determined if command TIMEOUT is available in which case this command will be used later for a delay of one second (Windows Vista and later Windows client versions) or if command PING must be used for the one second delay (Windows XP).
Then the subroutine WaitForBatch is called the first time with the batch file First.bat.
The subroutine uses the command START to start one more command process in a new console window with window title Run First.bat with ignoring the AutoRun registry string value which by Windows default does not exist.
This second cmd.exe instance keeps running after execution of the command line specified next with the other arguments is finished. The command line for second cmd.exe requires the execution of a third cmd.exe again with ignoring AutoRun registry string value if existing at all to execute the batch file First.bat specified with fully qualified file name. The third cmd.exe instances closes itself on finishing processing of the batch file.
The second cmd.exe changes now the title of its console window to Finished First. Important is here that the batch file extension is not anymore in the window title.
The first cmd.exe instance processing Main.bat continues with batch file processing already after successful start of second cmd.exe. It uses the command to wait one second and then runs TASKLIST to output all running cmd.exe processes with verbose information which is redirected to command FIND to search case-insensitive for the batch file name First.bat.
As long as there is a cmd.exe process running with First.bat, the first cmd.exe continues batch file processing of Main.bat inside subroutine WaitForBatch in a loop with a jump to CheckBatchRun. Otherwise the subroutine is left and processing of Main.bat continues with the second CALL of WaitForBatch with Second.bat.
Finally Main.bat changes also its window title to Finished Main and prompts the user to press any key in case of Main.bat execution was started with a double click on this file in Windows Explorer.
First.bat takes a very long time to finish as thousands of file names must be output into the console window of second cmd.exe. It is possible to click on the X symbol of console window with title Run First.bat to terminate immediately the execution of second and of third cmd.exe which results in first cmd.exe continues with starting two more cmd.exe for processing Second.bat.
It is also possible to interrupt the long running First.bat by pressing Ctrl+C and answer the prompt for termination of batch job with Y (on English Windows) resulting in third cmd.exe stopping really the processing of First.bat and second cmd.exe keeps running showing the output of First.bat and changing the window title of its console window to Finished First. This is detected by first cmd.exe processing Main.bat and it starts the processing of Second.bat.
The disadvantage of this solution is that on pressing Ctrl+C in console window with title Run First.bat while DIR outputs all the file names and pressing now N (on English Windows) results nevertheless in a termination of the batch job. I am not 100% sure why this happens. I have just a supposition for this behavior.
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 /?
cmd /?
dir /?
echo /?
endlocal /?
find /?
goto /?
if /?
pause /?
ping /?
setlocal /?
start /?
tasklist /?
timeout /?
title /?

Handle Windows command prompt input from keyboard and display output and also redirecting it to a file?

Though I can find few relevant questions such as Displaying Windows command prompt output and redirecting it to a file and How do I echo and send console output to a file in a bat script?, I could not fix my problem. I am working on Windows XP and running a few scripts using a batch file which uses STDIN and STDOUT handles.
Basically, I want to save the log file of command prompt. This is possible with "echo >> log.txt" in a batch file. However, this is not saving the outputs generated as a result of the script file. So I tried at the cmd prompt itself as D:>file.bat >"dir_path/log.txt". Again, this command saves the STDOUT to log.txt at the specified location. Since I need to get a few user inputs i.e. to use the STDIN handle, how do I achieve this in addition to saving the outputs of command prompts in separate file too?
The answer is simple:
#echo off
set /p answ1=Get user input1
set /p answ2=Get User input2
echo %answ1% and %answ2%>>log.txt
notepad log.txt
set /p "var=<log.txt"
type log.txt
Even if you redirect your .bat file to a file, you can output to the screen with >con.
Execute the following script with test.bat >test.out. It will prompt you for an input on the screen.
timeout -t 2
>con set /p "var1=Prompt1: "
ipconfig
>con set /p "var2=Prompt2: "
echo %var1% %var2%
>con echo %var1% %var2%
exit /b

Update Batch File: Implementing Conditional Arguments

I work in IT help-desk, new to coding but put together this batch file to get our nightly updates completed faster:
#echo off
echo.
echo RTC Customer Care - Variety Pre-Eigen Updater
echo (Continue along with 'ENTER' to reach desired update.)
echo.
pause
echo.
echo ====================================
echo Transfer Required Files to C: Drive?
echo ====================================
echo.
echo.
pause
cd /d h:\smsback
call vwiw3net2.bat
echo.
echo (Finished copying files)
echo Note: If transfer failed, re-run updater.
pause
echo.
echo ===========================
echo Execute Part 1/2 of Update?
echo ===========================
echo.
echo.
pause
echo (Follow prompts till completion)
start /d "c:\smsback\1_win3_1" WindowsInstaller-KB893803-v2-x86.exe
pause
echo.
echo ===========================
echo Execute Part 2/2 of Update?
echo ===========================
echo.
echo.
pause
echo (Follow prompts till completion)
echo Note: 2nd update takes a few minutes to display.
start /d "c:\smsback\2_net2" NetFx20SP2_x86.exe
pause
echo.
echo.
echo ==================================================
echo ATTENTION: Register will RESTART to finish update.
echo ==================================================
echo.
pause
shutdown.exe /r /t 05
(goto) 2>nul & del "%~f0"
What would be some good conditional arguments for verifying that an update installed? File size? Just don't want to have to run the script to get to update 2 and open/close out of previous steps.
First, opening a command prompt window and running there start /? or help start results in getting help displayed for this command. It can be read on output help about /Dpath and other options of this command. There is no space between /D and path.
Second, start interprets first double quoted string as title. Therefore "" or "useful title" should be specified on command line with start as first parameter if any other parameter is enclosed in double quotes.
Third, if start is used to install from within a batch file, it is better to use this command with parameter /wait as it is not possible to run multiple installations parallel. msiexec used to install each security update does not allow running more than one install/repair/uninstall operation at the same time.
Fourth, most executables of Windows security updates are console applications and can be run from within a batch file without the need to use command start at all. So instead of
start /d "c:\smsback\1_win3_1" WindowsInstaller-KB893803-v2-x86.exe
it would be better to use just:
C:\smsback\1_win3_1\WindowsInstaller-KB893803-v2-x86.exe
Fifth, the executables of Windows security updates all exit with a value greater 0 on an error and with 0 on success. Therefore after running a security update executable without command start as written above a line like the following could be used to check return value of the executable.
if errorlevel 1 echo Failed to install KB893803-v2-x86, error code %ERRORLEVEL%.
See Windows Installer Error Messages and MsiExec.exe and InstMsi.exe Error Messages.
And finally which updates are installed already can be queried from Windows registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Updates and its subkeys.

Batch file to determine if using Command Prompt

The last line in my batch file is pause. Is there any way to add a if condition to see if the script is run within command prompt or by double clicking to execute? I want to skip pause if it's running in command prompt.
...
...
if not RUN_IN_COMMAND_PROMPT (
pause
)
EDIT:
Hope to find a solution works in Windows Server 2003/2008, WinXP, Win7.
CALL :GETMYSWITCH %CMDCMDLINE%
IF /I "%MYSWITCH%" == "/C" ECHO I WAS STARTED IN THE EXPLORER & PAUSE
IF /I NOT "%MYSWITCH%" == "/C" ECHO I WAS STARTED IN A DOS SESSION
:GETMYSWITCH
SET MYSWITCH=%2
I know this is a year later but for future people searching you can use
If /I "%COMSPEC%" == %CMDCMDLINE% Goto SkipPause
pause
:SkipPause
It will skip the pause block if running from the command line and pause if running from batch file.
By definition, a shell script is always going to be run in a "command prompt". But try using the SESSIONNAME env var - it seems to NOT be present if the script was started by double-clicking instead of manually running it from a prompt.
Use the tty command.
Use the -s option and check the return value.

Pausing a batch file when double-clicked but not when run from a console window?

Is there a way for a batch file (in this case, running on Windows XP) to determine whether it was launched from a command line (i.e. inside a console window) or launched via the shell (e.g. by double-clicking)?
I have a script which I'd like to have pause at certain points when run via the shell, but not when run at a command line. I've seen a similar question on SO, but am unable to use the same solution for two reasons: first, whether or not it pauses needs to be dependent on multiple factors, only one of which is whether it was double-clicked. Second, I'll be distributing this script to others on my team and I can't realistically ask all of them to make registry changes which will affect all scripts.
Is this possible?
Found one :-) – After desperately thinking of what cmd might do when run interactively but not when launching a batch file directly ... I finally found one.
The pseudo-variable %cmdcmdline% contains the command line that was used to launch cmd. In case cmd was started normally this contains something akin to the following:
"C:\Windows\System32\cmd.exe"
However, when launching a batch file it looks like this:
cmd /c ""C:\Users\Me\test.cmd" "
Small demo:
#echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
This way of checking might not be the most robust, though, but /c should only be present as an argument if a batch file was launched directly.
Tested here on Windows 7 x64. It may or may not work, break, do something weird, eat children (might be a good thing) or bite you in the nose.
A consolidated answer, derived from much of the information found on this page (and some other stack overflow pages with similar questions). This one does not rely on detecting /c, but actually checks for the name of the script in the command line. As a result this solution will not pause if you double-clicked on another batch and then called this one; you had to double-click on this particular batch file.
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
The variable "testl" gets the full line of the cmd processor call, stripping out all of the pesky double quotes.
The variable "testr" takes "testl" and further strips outs the name of the current batch file name if present (which it will be if the batch file was invoked with a double-click).
The if statement sees if "testl" and "testr" are different. If yes, batch was double-clicked, so pause; if no, batch was typed in on command line (or called from another batch file), go on.
Edit: The same can be done in a single line:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
In plain English, this
pipes the value of %cmdcmdline% to findstr, which then searches for the current script name
%0 contains the current script name, of course only if shift has not been called beforehand
%~nx0 extracts file name and extension from %0
>NUL 2>&1 mutes findstr by redirecting any output to NUL
findstr sets a non-zero errorlevel if it can't find the substring in question
&& only executes if the preceding command returned without error
as a consequence, standalone will not be defined if the script was started from the command line
Later in the script we can do:
if defined standalone pause
One approach might be to create an autoexec.nt file in the root of c:\ that looks something like:
#set nested=%nested%Z
In your batch file, check if %nested% is "Z" - if it is "Z" then you've been double-clicked, so pause. If it's not "Z" - its going to be "ZZ" or "ZZZ" etc as CMD inherits the environment block of the parent process.
-Oisin
A little more information...
I start with a batch-file (test.cmd) that contains:
#echo %cmdcmdline%
If I double-click the "test.cmd" batch-file from within Windows Explorer, the display of echo %cmdcmdline% is:
cmd /c ""D:\Path\test.cmd" "
When executing the "test.cmd" batch-file from within a Command Prompt window, the display of
echo %cmdcmdline% depends on how the command window was started...
If I start "cmd.exe" by clicking the "Start-Orb" and "Command Prompt" or if I click "Start-Orb" and execute "cmd.exe" from the search/run box. Then I execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\system32\cmd.exe"
Also, for me, if I click "Command Prompt" from the desktop shortcut, then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is also:
"C:\Windows\system32\cmd.exe"
But, if I "Right-Click" inside a Windows Explorer window and select "Open Command Prompt Here", then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\System32\cmd.exe" /k ver
So, just be careful, if you start "cmd.exe" from a shortcut that contains a "/c" in the "Target" field (unlikely), then the test in the previous example will fail to test this case properly.

Resources