最後のいくつかの作業は、多くの Windows 専用のエンジンやツールを含む必要があるため、しばらくは Windows 環境から離れられません(サボることができません)が、錬金術の需要があるため、WSL を試してみることにしました。移動可能で Windows に優しい Ubuntu インスタンスをインストールします。
WSL Ubuntu のインストール#
Microsoft Store から WSL Ubuntu インスタンスを取得します。
ここでは、Clash ユーザーが Store を開けない場合があるため、Clash 設定で UWP Loopback を設定し、Store - Save にチェックを入れるだけです。
インストールパッケージはC:\Program Files\WindowsApps\CanonicalGroupLimited.Ubuntu22.04LTS_2204.5.10018.0_x64__79rhkp1fndgsc
で見つけることができ、そのサイズは一定です。
実際のシステム内容は、%LocalAppData%\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc
に保存されています。
したがって、他のドライブに移動する必要があります。
インストールパッケージの抽出#
管理者として PowerShell を開き、Windows Linux サブシステムのサポートをインストールします。
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
インストールが完了したら、Y を押して再起動します。
その後、WSL のモードを設定できます。
wsl --set-default-version 1
wsl1 と wsl2 の違いは、wsl2 がシステムの完全な隔離を実現しているのに対し、wsl1 は Linux のファイルを NTFS システムに直接表示します。wsl 2 を設定した場合、インストール時に
WslRegisterDistribution failed with error: 0x800701bc
というエラーが発生する可能性があります。
これは、対応する wsl2 のカーネルがないためで、wsl の公式サイトから更新パッケージをダウンロードする必要があります。
インストールパッケージの場所に移動し、パッケージを移動ハードドライブにコピーします(ここでは F:)。
実行可能ファイルをダブルクリックしてインストールします。
ここで、インストール画面が「intalling ...」で長時間止まってしまう問題に直面しました。GitHub の issue で解決策が提案されました:同じ問題が発生しましたが、回避策を見つけました:ctrl+c を使用すると、続行してユーザー名とパスワードを尋ねられます。
その後、無事にインストールが完了しました。私たちが選択したのは wsl 1 モードなので、F:\Ubuntu\rootfs
フォルダー内に Linux システムファイルが見えます。
これで、先ほど実行したインストールの実行可能ファイル(Ubuntu2204)を再度開いてテストできます。
内容のクリーンアップ#
スタートメニューから Ubuntu をアンインストールし、C ドライブのインストールパッケージを解放します。
移動ハードドライブからホストを切り離します。
レジストリの場所に移動します:
計算機\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss{*****}
最後の位置はランダムなGUID
で、開くと 2 つの重要な内容が表示されます:
BasePath : F:\Ubunut DistributionName: Ubuntu-22.04
path
は wsl、Linux インスタンスのディレクトリ(rootfs
)を指示するために使用され、name はこのインスタンスの名前(wsl –list
)を知らせるために使用されます。
残りのいくつかの項目は、ログインユーザーをアクティブにし、wsl モードを設定するための値です。とにかく、この情報があれば、コマンドラインから直接 wsl を起動できます:
wsl -d Ubuntu-22.04
このレジストリを Ubuntu ディレクトリにエクスポートします:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss{8f49723d-d252-404e-b36a-e376ee44c835}]
"State"=dword:00000001
"DistributionName"="Ubuntu-22.04"
"Version"=dword:00000002
"BasePath"="F:\Ubuntu"
"Flags"=dword:00000007
"DefaultUid"=dword:000003e8
別のホストでこのインスタンスを開く必要がある場合は、basepath を現在の移動ハードドライブの別のホストでのドライブ文字に変更するだけです(F: -> E:)、その後、このレジストリをダブルクリックして、別のホストにレジストリをインストールします。
複数の wsl インスタンスがある場合は、重複しないように注意が必要です。
バッチファイルを使用して実現します。
@echo off
setlocal EnableDelayedExpansion
set batfilenam=%~nx0
set batdir=%~dp0
set batdir=%batdir:~0,-1%
set batdir2=%batdir:=\%
set ThisWslDistributionName=%~1
set UnixUser=%~2
REM =========== BAT PARAMETER CHECKING ==============
if not defined ThisWslDistributionName (
echo. DistributionNameをパラメーターとして指定する必要があります。
echo. DistributionNameはLxssサービスに登録される新しい名前です。
echo. この.batはWin10.21H2以上と互換性があります。
echo. 例:
echo. %batfilenam% Ubuntu-22.04
echo. %batfilenam% Ubuntu-22.04 bob
exit /b 4
)
if not "" == "%~3" (
call :Echos エラー: パラメーターは1つまたは2つだけ指定する必要があります。
exit /b 4
)
call :HasSpaceChar %ThisWslDistributionName%
if %ERRORLEVEL%==1 (
call :Echos エラー: DistributionNameにはスペース文字を含めることはできません。
exit /b 4
)
if defined UnixUser (
call :HasSpaceChar %UnixUser%
if %ERRORLEVEL%==1 (
call :Echos エラー: UnixUserにはスペース文字を含めることはできません。
exit /b 4
)
set _u_param=-u %UnixUser%
) else (
set _u_param=
)
REM =========== ENV CHECKING ==============
set wsl1_checkdir=%batdir%\rootfs\root
set wsl1_seen=
if exist "%wsl1_checkdir%" set wsl1_seen=1
set wsl2_checkfile=%batdir%\ext4.vhdx
set wsl2_seen=
if exist "%wsl2_checkfile%" set wsl2_seen=1
if "%wsl1_seen%%wsl2_seen%" == "" (
call :Echos エラー: "%batdir%"にWSLファイルシステムが見つかりません。
call :Echos 次のいずれかを持っている必要があります
call :Echos "%wsl1_checkdir%" ^(WSL1用^)
call :Echos または
call :Echos "%wsl2_checkfile%" ^(WSL2用^)
exit /b 4
)
REM =========== PREPARE .REG FILE ==============
REM 現在のDistributionNameのためにGUIDを生成する必要があります。
REM %ThisWslDistributionName%を計算することで一意であることを保証できます。
echo %ThisWslDistributionName%> "%batdir%\wslname.tmp"
call :GetFileMD5 "%batdir%\wslname.tmp" md5
if not defined md5 (
call :Echos エラー: このWslDistributionNameのGUIDを生成できません。
exit /b 4
)
set md5guid=%md5:~0,8%-%md5:~8,4%-%md5:~12,4%-%md5:~16,4%-%md5:~20,12%
rem "Ubuntu-22.04"の場合、md5guidは
rem 2b0c8e79-b4a5-1bfc-49cd-4f344cbfe444
set md5finalchar=%md5:~31,1%
if not defined md5finalchar (
call :Echos エラー: このWslDistributionNameのMD5を生成する際に、certttil.exeが期待される結果を返しませんでした。
call :Echos md5=%md5%
exit /b 4
)
set badoutput=%md5:~32,1%
if defined badoutput (
call :Echos エラー: このWslDistributionNameのMD5を生成する際に、certttil.exeが期待される結果を返しませんでした。
call :Echos md5=%md5%
exit /b 4
)
set regfile=%batdir%\WSL-green.reg
echo Windows Registry Editor Version 5.00 >> "%regfile%"
echo.>> "%regfile%"
echo [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss{%md5guid%}]>> "%regfile%"
if defined wsl1_seen (
echo "Flags"=dword:00000007 >> "%regfile%"
set wslverhint=WSL1
) else if defined wsl2_seen (
echo "Flags"=dword:0000000f >> "%regfile%"
set wslverhint=WSL2
) else (
echo "wslバージョンが見つかりません" >> "%regfile%"
)
echo "BasePath"="%batdir2%" >> "%regfile%"
echo "DistributionName"="%ThisWslDistributionName%" >> "%regfile%"
type "%batdir%\WSL-green.reg.0" >> "%regfile%"
REM =========== IMPORTING REGISTRY ==============
call :Echos WSLインスタンスを次のように登録しています:
call :Echos . WSLバージョン = %wslverhint%
call :Echos . GUID = {%md5guid%}
call :Echos . DistributionName = %ThisWslDistributionName%
call :EchoAndExec reg import "%regfile%"
if not %ERRORLEVEL%==0 (
call :Echos レジストリファイルのインポートに失敗しました: %regfile%
pause
exit /b 4
)
title WSL - %ThisWslDistributionName%
call :EchoAndExec wsl -d %ThisWslDistributionName% %_u_param% --cd ~
if not %ERRORLEVEL%==0 (
echo.
echo "wsl -d"の実行に失敗しました。バッチファイルまたはWindows環境を確認してください。
echo.
pause
exit /b 4
)
exit /b 0
REM =============================
REM ====== 以下の関数 ======
REM =============================
:Echos
REM この関数は呼び出し元のために%ERRORLEVEL%を保持します。
REM LastErrorは呼び出し元を汚染しません。
setlocal & set LastError=%ERRORLEVEL%
echo [%batfilenam%] %*
exit /b %LastError%
:EchoAndExec
echo [%batfilenam%] EXEC: %*
call %*
exit /b %ERRORLEVEL%
:HasSpaceChar
REM 入力パラメーターにスペース文字が含まれているか確認します。
REM
REM call :HasSpaceChar param1 param2
REM call :HasSpaceChar "param1 param2"
REM -- ERRORLEVELは1になります。つまり、はい。
REM
REM call :HasSpaceChar ans param1-param2
REM -- ERRORLEVELは0になります。つまり、いいえ。
REM
REM 入力パラメーターがない場合は、「スペース文字がある」と見なします。
setlocal & set input=%*
if not defined input exit /b 1
set input=%input:"=#%
set count=0
for %%i in (%input%) do (
set /A count=count+1
)
if %count% == 1 (
exit /b 0
) else (
exit /b 1
)
:GetFileMD5
REM 感謝します: https://github.com/npocmaka/batch.scripts/blob/master/fileUtils/md5.bat
REM 使用法:
REM call :GetFileMD5
set "md5="
for /f "skip=1 tokens=* delims=" %%# in ('certutil -hashfile "%~f1" MD5') do (
if not defined md5 (
for %%Z in (%%#) do set "md5=!md5!%%Z"
)
)
endlocal && (set "%~2=%md5%")
今後はバッチファイルをダブルクリックするだけで、即座に使用可能になります。