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

Posted

技术标签:

【中文标题】为啥在 FreeCommander 中双击启动批处理文件时 CMD 找不到 wsl 命令?【英文标题】:Why is the wsl command not found by CMD on starting a batch file with a double click in FreeCommander?为什么在 FreeCommander 中双击启动批处理文件时 CMD 找不到 wsl 命令? 【发布时间】:2022-01-03 19:09:50 【问题描述】:

我想在登录时使用批处理脚本在适用于 Linux 的 Windows 子系统中启动 Docker。当我以管理员身份运行批处理文件时,它可以工作。所以我遵循了这个指南:Always Run Batch file as Administrator in 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 并重新安装它,但问题仍然存在。

【问题讨论】:

@Myrkjartan 那是因为您使用的是 32 位浏览器。扔掉它,改用 64 位的,或者由于某种原因你不能这样做,然后使用 C:\Windows\SysNative 重定向到真正的 system32 文件夹:Executable "C:\Windows\System32\Fodhelper.exe" not found,Jenkins: Run Windows batch commands in 32-bit mode 这能回答你的问题吗? Executable "C:\Windows\System32\Fodhelper.exe" not found 【参考方案1】:

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

WOW64 Implementation Details File System Redirector Registry Keys Affected by WOW64

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

    %SystemRoot%\System32 与 64 位应用程序默认使用的 64 位应用程序。 %SystemRoot%\SysWOW64 与 32 位应用程序默认使用的 32 位应用程序。

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

cmd.exe 正在使用 local 环境变量 PATHEXTPATH 搜索批处理文件中指定的文件What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?的全部详细信息

wsl.exe 属于在 AMD64 Windows 上仅作为 64 位版本存在于 %SystemRoot%\System32 的可执行文件集。由于文件系统重定向器,在 local PATH 中使用扩展形式的 %SystemRoot%\System32 时,%SystemRoot%\SysWOW64 中没有 32 位版本被 32 位 cmd.exe 搜索。因此,问题中发布的批处理文件不适用于 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

要了解所使用的命令及其工作原理,请打开command prompt 窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

echo /? endlocal /? exit /? for /? goto /? if /? netsh /? netsh interface /? netsh interface portproxy /? netsh interface portproxy add /? netsh interface portproxy add v4tov4 /? pause /? set /? setlocal /?

【讨论】:

以上是关于为啥在 FreeCommander 中双击启动批处理文件时 CMD 找不到 wsl 命令?的主要内容,如果未能解决你的问题,请参考以下文章

双击时如何使Windows批处理文件暂停?

如何防止执行批处理文件后自动关闭控制台

如何在资源管理器中双击文件被钩住?

确定是否已从命令行(cmd)启动/执行批处理脚本 - 或 - 要暂停还是不暂停?

在 Mac OS X 中双击文档文件以打开 Java 应用程序

使用 Process.Start() 访问 ssh