I want to use a batch script to start Docker in Windows Subsystem for Linux at login. It works when I run the batch file as administrator. So I followed this guide: Always Run Batch file as Administrator in Windows 10
Then I placed the shortcut into the Startup
folder. The script is started, but it exits always at the first line.
Then I tried to run manually the batch file in FreeCommander. The batch script works when I run the script as administrator via right click context menu item. But there is output an error message when I run the batch script with a double click. The output error message is:
The command "wsl" is either misspelled or could not be found.
This is the batch script:
FOR /F "tokens=* USEBACKQ" %%g IN (`wsl.exe sh -c "hostname -I"`) do (SET "ip=%%g")
netsh interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=%ip%
wsl sh -c "sudo dockerd -H tcp://%ip%"
I removed also once Windows Subsystem for Linux completely and reinstalled it, but the problem persists.
CodePudding user response:
There should be read first the following Microsoft documentation pages:
There are two system directories on 64-bit Windows with a processor with AMD64 architecture:
%SystemRoot%\System32
with 64-bit applications used by 64-bit applications by default.%SystemRoot%\SysWOW64
with 32-bit applications used by 32-bit applications by default.
The system environment variable PATH
contains by Windows default %SystemRoot%\System32
as first folder path. If a 32-bit application starts cmd.exe
to process a batch file, there is started 32-bit %SystemRoot%\SysWOW64\cmd.exe
because of the file system redirector.
cmd.exe
is searching for files specified in a batch file just with file name without or with file extension and without path by using the local environment variables PATHEXT
and PATH
as explained in full details by What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?
wsl.exe
belongs to the set of executables which on AMD64 Windows exists only as 64-bit version in %SystemRoot%\System32
. There is no 32-bit version in %SystemRoot%\SysWOW64
searched by 32-bit cmd.exe
on using %SystemRoot%\System32
in expanded form in local PATH
because of file system redirector. For that reason the batch file as posted in the question does not work on being processed by 32-bit cmd.exe
on Windows x64.
The solution is taking WOW64 into account with additional code in the batch file:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if exist %SystemRoot%\System32\wsl.exe set "FileNameWSL=%SystemRoot%\System32\wsl.exe" & goto RunWSLCommands
if exist %SystemRoot%\Sysnative\wsl.exe set "FileNameWSL=%SystemRoot%\Sysnative\wsl.exe" & goto RunWSLCommands
echo ERROR: Could not find wsl.exe. Script execution aborted.
@setlocal EnableDelayedExpansion & for /F "tokens=1,2" %%G in ("!CMDCMDLINE!") do @endlocal & if /I "%%~nG" == "cmd" if /I "%%~H" == "/c" pause
exit /B
:RunWSLCommands
for /F "tokens=*" %%g in ('%FileNameWSL% sh -c "hostname -I"') do set "ip=%%g"
%SystemRoot%\System32\netsh.exe interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=%ip%
%FileNameWSL% sh -c "sudo dockerd -H tcp://%ip%"
endlocal
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 /?
endlocal /?
exit /?
for /?
goto /?
if /?
netsh /?
netsh interface /?
netsh interface portproxy /?
netsh interface portproxy add /?
netsh interface portproxy add v4tov4 /?
pause /?
set /?
setlocal /?