Update Batch File: Implementing Conditional Arguments - windows

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.

Related

Batch Script to Echo another batch script

How can i do in batch file to echo (create) another batch file to run in windows start and delete it after running? [Trying WSl 2 installer with one batch script actually]
i tried this ,
#echo off
:: BatchGotAdmin
// asking one time admin priv code here
#echo off
title wsl setup Part 1 !
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
// and here is my another batch to need echo correctly in C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\ for run after reboot
(echo #echo off^
:: BatchGotAdmin
// admin priv for seconf batch
#echo off
title wsl setup part 2 !
//other steps for download kernel and set default wsl version here
echo "Setup Finished, Deleting this bat" && del C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\wsl-part2.bat && pause
) > "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\wsl-part2.bat"
//First batch again for asking reboot now or later
:PROMPT
SET /P REBOOTNOW=Do you want reboot now second script will run after reboot (Y/[N])?
IF /I "%REBOOTNOW%" NEQ "N" GOTO END
shutdown -r
:END
endlocal
But i stucked dism commands loop (because echo is not understant it is a string) and echo only to target file
#echo off:: BatchGotAdmin
Requesting administrative privileges...
Despite my comment to the contrary, if you wish to do this using such a complicated methodology, here's the general syntax for doing so:
( Echo #Echo Off
Echo Rem BatchGotAdmin
Echo // admin priv for second batch
Echo Title WSL Setup Part 2.
Echo // other steps for download kernel and set default WSL version here
Echo Echo Setup Finished, deleting this script.
Echo (GoTo^) 2^>Nul ^& Del "%%~f0"
) 1> "%ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp\wsl-part2.cmd"
You should note that I've changed the self deletion command, to something more efficient and functional. It decided to do that because it shows you that, using this method, you need to escape problematic characters with carets, (including ampersands, redirection symbols, pipes, and closing parentheses). You also need to escape % characters by doubling them.

Batch to check if process exists

I'd like a batch that will check if the process firefox.exe exists (after it has been started by the start command).
If the process exists, it will go to the label :fullscreen,
else the batch will go the the label :timeout. Then, it will check again if the process firefox.exe exists and if not, it will go again to the label :fullscreen until the process exists.
Here is my batch:
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
:timeout
timeout /t 5
:fullscreen
nircmd sendkeypress F11
exit
How can I do this check ?
You can also use QUERY PROCESS:
#Echo Off
If Not Exist "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe" Exit/B
Start "" "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe"
:Loop
Timeout 5 /NoBreak>Nul
QProcess firefox.exe>Nul 2>&1||GoTo :Loop
NirCmd SendKeyPress F11
I suggest for this task the batch file:
#echo off
start "" /max firefox.exe
if errorlevel 1 goto :EOF
set LoopCount=0
:WaitLoop
%SystemRoot%\System32\timeout.exe /T 5
%SystemRoot%\System32\tasklist.exe /FI "IMAGENAME eq firefox.exe" 2>nul | %SystemRoot%\System32\find.exe /I "firefox.exe" >nul
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
set /A LoopCount+=1
if not %LoopCount% == 6 goto WaitLoop
Let me explain the few command lines used here.
1. Starting Firefox
The command START being an internal command of cmd.exe interprets the first double quoted string as optional title for the console window. Therefore the command line
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
results just in opening a new console window with the window title:
C:\Program Files (x86)\Mozilla Firefox\firefox.exe
For that reason "" is specified as first START argument to define an empty title. Firefox is a GUI application. So no console window is opened which means an empty window title is really enough.
The parameter /max would not be really necessary, but the goal is to get Firefox into full screen mode after starting. So why not starting it already maximized?
32-bit version of Firefox is by default installed in directory %ProgramFiles% on 32-bit Windows and in %ProgramFiles(x86)% on 64-bit Windows. But it is possible during the installation to install Firefox into any other folder. But Firefox installer is well coded and registers firefox.exe in Windows registry under key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
This is recommended by Microsoft as written in MSDN article Application Registration.
The command START searches also in Windows registry under this key for an executable specified as argument without path as explained in answer on Where is “START” searching for executables?
This is the reason for using just firefox.exe on START command line because that starts an installed Firefox independent on installation location.
START displays an appropriate message box if firefox.exe could not be started and exits in this case with a return code greater 0 (9059 in my test on one computer).
The help output on running if /? in a command prompt window explains how to evaluate the exit code of a previous command or application without usage of immediate or delayed environment variable expansion and therefore working anywhere in a batch file from MS-DOS (really!) to currently latest Windows 10.
The command line if errorlevel 1 goto :EOF means IF start failed to start firefox.exe indicated by an exit code greater or equal 1 THEN exit execution of this batch file. For details on exiting batch file execution see answer on Where does GOTO :EOF return to?
2. Checking for running Firefox
The command TASKLIST being an external command, i.e. a console application in system directory of Windows, outputs a list of running processes. This list can be already filtered by TASKLIST itself for a specific process as done in batch file with /FI "IMAGENAME eq firefox.exe".
But TASKLIST is designed for just printing a list of processes. It is not designed for checking if a specific process is running and returning the result to the calling process via exit code. TASKLIST always exits with 0.
But an error message is output to handle STDERR on using a filter and no process can be found in process list matching this filter. For that reason 2>nul is used to suppress this error message by redirecting it to device NUL. Read the Microsoft article about Using Command Redirection Operators for more information about redirection.
A simple method to get a simple false/true respectively 0/1 result on checking for running Firefox is filtering output of TASKLIST with external command FIND which exits with 0 if the string to find was indeed found or with 1 if the searched string could not be found in the text read in this case from STDIN. The output of FIND is of no interest and therefore suppressed with redirection to device NUL using >nul.
Instead of using TASKLIST and FIND it is also possible to use QPROCESS:
%SystemRoot%\System32\qprocess.exe firefox.exe >nul 2>&1
QPROCESS exits with exit code 1 if firefox.exe could not be found in list of running processes. Otherwise the exit code is 0 on firefox.exe is running.
3. Evaluating Firefox process checking result
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
The IF command checks if exit code of FIND is NOT greater or equal 1 which means if exit code is lower than 1. Command FIND exits never with a negative value. So if this condition is true then it is time to execute nircmd.exe to send key press F11 to application in foreground hopefully being Firefox (not guaranteed by this code) and exit batch file processing.
Otherwise the batch file should wait once again 5 seconds and then do the check again. This can very easily result in an endless running batch file in case of started Firefox is immediately closed by the user before the 5 seconds wait timed out. For that reason it is counted how often the wait loop is already executed. After 6 loop runs, or 30 seconds, it is really time to no longer wait for Firefox and exit the batch file.
4. Getting more information about used commands
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.
echo /?
find /?
if /?
qprocess /?
set /?
start /?
tasklist /?
timeout /?
And Single line with multiple commands using Windows batch file should be also read explaining operator & in addition to all other web pages referenced already above.
You can show a list of opened programs like this:
tasklist
To check if firefox exists:
EDIT: Code edited to show a fully working example
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
goto :checkloop
:checkloop
tasklist|find "firefox.exe" > NUL
if %ERRORLEVEL% == 0 (
call :fullscreen
exit
) else (
call :timeout
goto :checkloop
)
:fullscreen
nircmd sendkeypress F11
goto :EOF
:timeout
timeout /t 5
goto :EOF

Running a batch file which requires inputs directly from folder

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.

Prevent batch file from closing after it executes an external .exe program

Believe it or not, I've searched all over stackoverflow and Google and can't find an answer to this that works for me.
(Windows 7 64-bit) I'm trying to create a batch file that runs multiple programs, one at a time. Simple, right? It works great until it runs the first .exe program. After the GUI of the .exe program closes, the batch file/cmd window also closes. I don't want it to close; I want the rest of the batch file to run.
Inside the batch file, I've tried the following methods, but none of them prevent the batch file from closing:
Git-1.9.5-preview20141217.exe
Git-1.9.5-preview20141217.exe
pause
call Git-1.9.5-preview20141217.exe
pause
start Git-1.9.5-preview20141217.exe
pause
start "" /wait Git-1.9.5-preview20141217.exe
pause
start "" /w Git-1.9.5-preview20141217.exe
pause
start "" /w /b Git-1.9.5-preview20141217.exe
pause
Does anyone know another method I can try? Maybe I should just call a powershell command or even translate the whole batch file to powershell, but I was trying to avoid powershell so that this script would work on multiple versions of Windows.
EDIT
I should also mention that with the methods above, the script closes before the pause command can be executed.
EDIT
Here's the full script with the rest of the .exe programs:
:Git
#echo off
(
echo.
echo.
echo DOWNLOADING GIT...
)
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://github.com/msysgit/msysgit/releases/download/Git-1.9.5-preview20141217/Git-1.9.5-preview20141217.exe', 'Git-1.9.5-preview20141217.exe')"
(
echo.
echo.
echo LAUNCHING GIT INSTALLATION PROGRAM...
echo.
echo !IMPORTANT! WHEN YOU REACH THE SCREEN 'Adjusting your PATH environment',
echo SELECT 'Use Git from the Windows Command Prompt'.
echo KEEP ALL OTHER OPTIONS AT THE DEFAULT SETTING.
echo.
echo AFTER READING THE INSTRUCTIONS ABOVE, PRESS ANY KEY TO CONTINUE
)
pause
Git-1.9.5-preview20141217.exe
pause
GOTO CheckOS
:CheckOS
IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:32BIT
(
echo.
echo.
echo 32 BIT
echo.
echo DOWNLOADING TORTOISEHG (MERCURIAL)...
)
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://bitbucket.org/tortoisehg/files/downloads/tortoisehg-3.2.4-x86.msi', 'tortoisehg-3.2.4-x86.msi')"
(
echo.
echo.
echo LAUNCHING TORTOISEHG INSTALLATION PROGRAM...
)
tortoisehg-3.2.4-x86.msi
GOTO MingW
:64BIT
(
echo.
echo.
echo 64 BIT
echo.
echo DOWNLOADING TORTOISEHG (MERCURIAL)...
)
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://bitbucket.org/tortoisehg/files/downloads/tortoisehg-3.2.4-x64.msi', 'tortoisehg-3.2.4-x64.msi')"
(
echo.
echo.
echo LAUNCHING TORTOISEHG INSTALLATION PROGRAM...
)
tortoisehg-3.2.4-x64.msi
GOTO MingW
:MingW
(
echo.
echo.
echo DOWNLOADING MINGW...
)
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://downloads.sourceforge.net/project/mingwbuilds/mingw-builds-install/mingw-builds-install.exe?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fmingwbuilds%2F%3Fsource%3Dtyp_redirect&ts=1422376004&use_mirror=iweb', 'mingw-builds-install.exe')"
(
echo.
echo.
echo LAUNCHING MINGW INSTALLATION PROGRAM...
)
mingw-builds-install.exe
(
echo.
echo.
echo DONE! PRESS ANY KEY TO CLOSE.
)
pause
GOTO END
:END
For the lines that run the external .exe program, I've tried all 7 forms of the command that were listed at the beginning of this question, yet the script always closes before reaching the next pause command. I've also tried using cmd.exe /c and cmd.exe /k from the suggestions below, but unfortunately the script still quits before reaching the pause command.
EDIT
I figured out the problem (though not how to fix it). If I remove these lines:
GOTO CheckOS
:CheckOS
IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:32BIT
so that the following commands are under the same batch label, it works! But I'm not sure why including the :CheckOS label causes it to break. I've used this label in other batch scripts before, and they worked fine.
Nevermind, sorry. :S This only worked if the program had already been run. If it had already been run, a "modify, repair, or remove" screen popped up instead of an "install" screen. Apparently only the "install" screen closes the cmd.exe window.
FINAL EDIT
The parentheses were the problem. After removing them, everything else worked. Method number 1 at the beginning of this question works after removing the parentheses.
Try opening the executable in a new shell:
#echo off
cmd.exe /c Git-1.9.5-preview20141217.exe
echo Still here.
The /c switch tells the (new) shell to close when the program terminates. Execution of the batch script will be suspended until then.
For example:
#echo off
echo New window.
cmd.exe /c %WINDIR%\system32\notepad.exe
echo Window still open.
cmd.exe /c %WINDIR%\system32\notepad.exe
echo Window closed. You won't see this.

Batch Scripting: Command Not Running With If Statement

So for starters, I'm kind of a scrub coder and I'm enjoying playing around with batch scripting.
I don't like to have multiple command line windows open, so I'm trying to script everything into this 1 batch file, including the ability to run standard command line commands.
Here's the section of my code that I'm having issues with.
:three
echo.
echo ***************************
echo **Enhanced Command Prompt**
echo ***************************
:three.b
echo.
set /p Return=Enter Command:
if '%Return%'=='Return' goto home
cmd /c %Return%
goto three.b
NOTE: I've also removed cmd /c, and %Return% excutes with no issue, but for the sake personal preference, I've kept the cmd /c present.
The issue with this line of text, is executing a command such as "Ping Google.com" crashes the window. So does ipconfig /all, and anything else that doesn't seem to execute right away.
If I remove the "IF=Return", then I have no problems running ping google.com or anything else, but I'm ultimately trapped in this section of code without that IF statement.
The IF statement itself functions, but "Ping X" and other commands do not without crashing the batch file.
Any help would be appreciated.
Thanks!
You will need to use double quotes in if as this is the proper way of quoting/comparing strings in batch file.
:three
echo.
echo ***************************
echo **Enhanced Command Prompt**
echo ***************************
:three.b
echo.
set /p Return=Enter Command:
if "%Return%" == "Return" goto home
cmd /c %Return%
goto three.b

Resources