Issue
I have a windows bat file and facing issue that set path command present in if condition is getting executed.
set browser=chrome
echo Browser value: %browser%
if "%browser%"=="chrome" (
echo "Browser passed is Chrome"
echo Chrome browser version before upgrade
reg query "HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon" /v version
echo Upgrade chrome browser to the latest version
choco upgrade googlechrome -y --ignore-checksums
echo Check the exit code of googlechrome upgrade command
if %ERRORLEVEL% neq 0 (
echo "Failed to upgrade googlechrome."
exit /b 1
)
echo "Chrome browser is upgraded successfully. Chrome browser version after upgrade,"
reg query "HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon" /v version
:: Install chromedriver using curl
echo "Install chromedriver from official google website"
C:
cd Users\myuser\Downloads
echo Set the installation directory
set "INSTALL_DIR=C:\Users\myuser\Downloads"
set DESTINATION_DIR=H:
echo Download latest chromeDriver for 32-bit Windows
set browserVersion=curl https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE
curl -o "%INSTALL_DIR%\chromedriver-win32.zip" https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/%browserVersion%/win32/chromedriver-win32.zip
:: Check the exit code of the chromedriver download command
if %ERRORLEVEL% neq 0 (
echo "Failed to install chromedriver."
exit /b 1
)
echo "Chromedriver installation is successful."
unzip chromedriver-win32.zip -d %DESTINATION_DIR%
echo Add the directory to the system's PATH
set PATH=%DESTINATION_DIR%\chromedriver-win32;%PATH%
echo %PATH%
H:
echo "Current chromedriver version"
chromedriver -version
) else (
echo this is else *****
)
Before actual execution set path command is being executed.
Output is:
C:\Users\myuser>set browser=chrome
C:\Users\myuser>echo Browser value: chrome
Browser value: chrome
\<abc>\<def> was unexpected at this time.
C:\Users\myuser> set PATH=\chromedriver-win32;C:\Program Files\Docker\Docker\Resources\bin;<.... rest of the path>
C:\Users\myuser>
Even tried with setx as below and facing same issue, setx /M PATH "%DESTINATION_DIR%\chromedriver-win32;%PATH%"
Automation is totally blocked due to this issue, appreciate any help!
Solution
There should be read first Variables are not behaving as expected as well as How does the Windows Command Interpreter (CMD.EXE) parse scripts? The entire command block beginning with (
in the line with the condition if "%browser%"=="chrome"
and ending with )
on the command line ) else (
as well as the small else
command block are parsed completely by the Windows Command Processor with expanding all variable references with syntax %VariableName%
before the IF condition is evaluated at all.
The simple solution is avoiding such large command blocks using an IF condition with command GOTO to control the command execution sequence. The Windows Command Processor is designed for such one command line after the other command execution behavior in comparison to more modern script interpreters which support blocks completely different.
The batch file code uses two techniques for avoiding command blocks:
- IF conditions with command GOTO like
if /I not "%browser%" == "chrome" goto OtherBrowser
. - Command operators like
&
as described by single line with multiple commands using Windows batch file.
There is absolutely no need to modify local, user or system environment variable PATH
for this task. The finally installed chromedriver.exe
can be simply referenced with its well-known fully qualified file name. Please take a look on What is the reason for "X is not recognized as an internal or external command, operable program or batch file"? It explains in full details how the environment variable PATH
is managed by Windows and used by the Windows Command Processor cmd.exe
.
The batch file below is completely rewritten. It first checks the existence of needed executables like curl.exe
, choco.exe
and tar.exe
. Their existence depends on version of Windows (curl.exe
and tar.exe
) respectively Chocolatey (choco.exe
). The batch file exits with an appropriate error message and exit code 10 on one of these three programs does not exist where expected respectively cannot be found.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Check the existence of curl.exe required for downloading Google ChromeDriver.
if exist %SystemRoot%\System32\curl.exe set "CurlExe=%SystemRoot%\System32\curl.exe" & goto CheckChoco
for %%I in (curl.exe) do set "CurlExe=%%~$PATH:I"
if not defined CurlExe echo ERROR: File not found: curl.exe& exit /B 10
:CheckChoco
rem Check the existence of choco.exe required for upgrading Google Chrome.
for %%I in (choco.exe) do set "ChocoExe=%%~$PATH:I"
if not defined ChocoExe echo ERROR: File not found: choco.exe& exit /B 10
rem Check the existence of tar.exe required for extraction of ZIP files.
if not exist %SystemRoot%\System32\tar.exe echo ERROR: File not found: tar.exe& exit /B 10
set "browser=chrome"
echo Browser value: %browser%
if /I not "%browser%" == "chrome" goto OtherBrowser
echo Browser passed is Chrome.
for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY HKCU\Software\Google\Chrome\BLBeacon /v version 2^>nul') do if /I "%%I" == "version" if not "%%K" == "" echo Chrome browser version before upgrade: %%K
echo Upgrading Chrome browser to the latest version...
"%ChocoExe%" upgrade googlechrome -y --ignore-checksums
if errorlevel 1 echo ERROR: Failed to upgrade Google Chrome.& exit /B 1
echo Chrome browser is upgraded successfully.
for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY HKCU\Software\Google\Chrome\BLBeacon /v version 2^>nul') do if /I "%%I" == "version" if not "%%K" == "" echo Chrome browser version after upgrade: %%K
rem Determine the user's preferred downloads folder.
set "DownloadsFolder="
for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "{374DE290-123F-4565-9164-39C4925E467B}" 2^>nul') do if /I "%%I" == "{374DE290-123F-4565-9164-39C4925E467B}" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "DownloadsFolder=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "DownloadsFolder=%%~K"
if not defined DownloadsFolder for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "{374DE290-123F-4565-9164-39C4925E467B}" 2^>nul') do if /I "%%I" == "{374DE290-123F-4565-9164-39C4925E467B}" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "DownloadsFolder=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "DownloadsFolder=%%~K"
if not defined DownloadsFolder set "DownloadsFolder=\"
if "%DownloadsFolder:~-1%" == "\" set "DownloadsFolder=%DownloadsFolder:~0,-1%"
if not defined DownloadsFolder set "DownloadsFolder=%UserProfile%\Downloads"
if not exist "%DownloadsFolder%\" md "%DownloadsFolder%"
rem Determine version of latest stable release of Google ChromeDriver.
set "LatestRelease="
for /F %%I in ('"%CurlExe%" -s https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE') do set "LatestRelease=%%I"
if not defined LatestRelease echo ERROR: Failed to determine latest release version of Google ChromeDriver.& exit /B 2
set "ChromeDriverFile=%DownloadsFolder%\chromedriver-win32.zip"
echo Downloading 32-bit ChromeDriver to: "%ChromeDriverFile%"
del /A /F "%ChromeDriverFile%" 2>nul
"%CurlExe%" -s -o "%ChromeDriverFile%" "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/%LatestRelease%/win32/chromedriver-win32.zip"
if errorlevel 1 echo ERROR: Failed to download Google ChromeDriver ZIP file.& exit /B 3
if not exist "%ChromeDriverFile%" echo ERROR: Missing file: "%ChromeDriverFile%"& exit /B 4
echo Extracting the ChromeDriver ZIP archive file...
%SystemRoot%\System32\tar.exe -x -f "%ChromeDriverFile%" -C H:\
if errorlevel 1 echo ERROR: Failed to extract file: "%ChromeDriverFile%"& exit /B 5
del "%ChromeDriverFile%"
echo ChromeDriver installation to H:\ is successful.
echo Current ChromeDriver version:
H:\chromedriver.exe -version
goto EndBatch
:OtherBrowser
echo this is else *****
:EndBatch
endlocal
There is a case-insensitive string comparison used to determine if the batch file should update Google Chrome and install latest stable release version of Google ChromeDriver or continue the batch file processing below the label OtherBrowser
. See symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files for details on how a string comparison is done by the internal command IF of CMD.
There should be used the command CHOICE if there is in real batch file a choice menu prompting the user which browser to update. Read the answer on: How to stop Windows command interpreter from quitting batch file execution on an incorrect user input? It explains in full details how to use %SystemRoot%\System32\choice.exe
and what are the reasons for making the usage of this Windows command much better for a choice prompt than the command set /P
.
There is no need for changing the current working directory in the entire batch script which is the reason why command CD is not used at all. The usage of fully qualified file and folder names is best as more fail safe and faster than working with relative paths and incomplete file names.
The directory %USERPROFILE%\Downloads
is just the Windows default for the folder into which Internet browsers download by default files. A user can change the preferred Downloads folder easily with a few mouse clicks as other shell folders. The code used to get the fully qualified folder name of the preferred Downloads folder is described in full details in my answer on How to create a directory in the user's desktop directory? There is just the registry value name and the environment variable name changed to determine the user's downloads directory.
There should be run once in a command prompt window:
reg QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
reg QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
The output of all registered shell folders should help in understanding the code for getting the fully qualified Downloads folder name.
The execution of if /?
or help if
in a command prompt window results in output of the usage help for the command IF. There is explained on first output help page which syntax to use for evaluation of the exit code of a command or executable assigned to the dynamic (not environment) variable ERRORLEVEL
. The answer on Difference between Dynamic Environment Variables and Normal Environment Variables in CMD demonstrates the advantages of using the recommended syntax IF ERRORLEVEL 1
or usage of conditional command operator ||
in comparison to the worst syntax if %ERRORLEVEL% neq 0
.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
choco --help
cmd /?
curl --help
del /?
echo /?
endlocal /?
exit /?
for /?
goto /?
if /?
md /?
reg /?
reg query /?
rem /?
set /?
setlocal /?
tar --help
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul
. The redirection operator >
must be escaped with caret character ^
on the FOR command lines to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with using a separate command process started in background with %ComSpec% /c
and the command line inside '
as additional arguments.
Answered By - Mofi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.