为什么在 FreeCommander 中双击启动批处理文件时 CMD 找不到 wsl 命令?

问题描述 投票:0回答:1

我想使用批处理脚本在登录时在适用于 Linux 的 Windows 子系统中启动 Docker。当我以管理员身份运行批处理文件时它起作用。所以我遵循了本指南:始终在 Windows 10 中以管理员身份运行批处理文件

然后我将快捷方式放入

Startup
文件夹中。脚本已启动,但总是在第一行退出。

然后我尝试在FreeCommander中手动运行批处理文件。当我通过右键单击上下文菜单项以管理员身份运行脚本时,批处理脚本将起作用。但是当我双击运行批处理脚本时,会输出一条错误消息。输出错误信息为:

命令“wsl”拼写错误或找不到。

这是批处理脚本:

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%"

我也完全删除了一次 Windows Subsystem for Linux 并重新安装它,但问题仍然存在。

batch-file windows-10 wsl-2 autostart
1个回答
3
投票

应首先阅读以下 Microsoft 文档页面:

AMD64 架构处理器的 64 位 Windows 上有 两个 系统目录:

  1. %SystemRoot%\System32
    64 位应用程序默认使用 64 位应用程序。
  2. %SystemRoot%\SysWOW64
    32 位应用程序默认使用 32 位应用程序。

system 环境变量

PATH
Windows 默认包含
%SystemRoot%\System32
作为第一个文件夹路径。如果 32 位应用程序启动
cmd.exe
来处理批处理文件,则由于文件系统重定向器而启动 32 位
%SystemRoot%\SysWOW64\cmd.exe

cmd.exe
正在使用 local 环境变量
PATHEXT
PATH
搜索批处理文件中指定的文件,其中仅包含文件名,不带或带文件扩展名,并且不带路径,如 What is the 详细说明“X 不被识别为内部或外部命令、可运行程序或批处理文件”的原因?

wsl.exe
属于可执行文件集,在 AMD64 Windows 上仅以
%SystemRoot%\System32
中的 64 位版本存在。由于文件系统重定向器的原因,在
local
%SystemRoot%\SysWOW64
中以扩展形式使用
cmd.exe
时,通过 32 位 %SystemRoot%\System32 搜索到的
PATH
中没有 32 位版本。因此,问题中发布的批处理文件无法在 Windows x64 上由 32 位
cmd.exe
处理。

解决方案是将 WOW64 考虑在内,并在批处理文件中添加附加代码:

@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

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • goto /?
  • if /?
  • netsh /?
  • netsh interface /?
  • netsh interface portproxy /?
  • netsh interface portproxy add /?
  • netsh interface portproxy add v4tov4 /?
  • pause /?
  • set /?
  • setlocal /?
© www.soinside.com 2019 - 2024. All rights reserved.