WSLでGUIアプリを実行する

#1.この記事の内容

Windows 11 ビルド22000以降で，LinuxのGUIアプリを実行できるようになったらしいので，試してみました．
GUIアプリの起動時に```cannot open display```のエラーが出て対策試行の経緯も記載しています．

普段はWSLからDockerを起動して作業していますので，コンテナ上からGUIアプリ起動まで試します．

##1-1.使用環境

* Windows11 ビルド
* PythonのGUI処理の動作を確認

#2.Windows 11アップデート

##2-1.アップデート前の準備(アップデート要件への対応)

手元の環境では，Windows11へのアップデート要件のうち，TPM 2.0とセキュアブートの2点で引っかかりました．

###2-1-1.TPM 2.0

筆者のPCはASUSマザーボード＋Indel CPUの構成で，[[Motherboard] ASUS マザーボードに Windows 11 をインストールする方法は?](https://www.asus.com/jp/support/FAQ/1046215/)に記載の手順で要件をクリアできました．

###2-1-2.セキュアブート

セキュアブートの設定は[Windows 11導入に必要なBIOS/UEFI設定メモ](https://blog.mizarsid.net/2021/07/05/bios-win11/)に記載の手順で要件をクリアできました．
mbr2gptを実行する際には，コマンドプロンプトを管理者権限で起動する必要があります．

```
> mbr2gpt /validate /disk:0 /allowFULLOS
MBR2GPT: Attempting to validate disk 0
MBR2GPT: Retrieving layout of disk
MBR2GPT: Validating layout, disk sector size is: 512 bytes
MBR2GPT: Validation completed successfully
> mbr2gpt /convert /disk:0 /allowFULLOS

MBR2GPT will now attempt to convert disk 0.
If conversion is successful the disk can only be booted in GPT mode.
These changes cannot be undone!

MBR2GPT: Attempting to convert disk 0
MBR2GPT: Retrieving layout of disk
MBR2GPT: Validating layout, disk sector size is: 512 bytes
MBR2GPT: Trying to shrink the OS partition
MBR2GPT: Creating the EFI system partition
MBR2GPT: Installing the new boot files
MBR2GPT: Performing the layout conversion
MBR2GPT: Migrating default boot entry
MBR2GPT: Adding recovery boot entry
MBR2GPT: Fixing drive letter mapping
MBR2GPT: Conversion completed successfully
MBR2GPT: Update WinRE config file
MBR2GPT: Before the new system can boot properly you need to switch the firmware to boot to UEFI mode!
```

##2-2.Windows11 アップデート

Windows Updateからのアップデートで正常にアップデートできました．

#3.Linux GUIアプリを実行する

[Linux 用 Windows サブシステムで Linux GUI アプリを実行する (プレビュー)](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps)の手順にそって，GUIアプリの動作確認を行います．

既に[NVIDIA WSL 用 GPU ドライバー](https://developer.nvidia.com/cuda/wsl)のインストールとWSLのインストールは完了していたので，事前準備は[既存の WSL インストール](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps#existing-wsl-install)のみを行いました．

##3-1.WSLをアップデートする

PowerShellを管理者として実行して下記コマンドでWSLをアップデートします．

```
> wsl --update
> wsl --shutdown
```

##3-2.geditでGUIアプリの起動確認を行う

```
$ sudo apt update
$ sudo apt install gedit -y
$ export DISPLAY=:0.0
$ gedit test.txt
```

ディスプレイに接続できないというエラーが出ました．
[3-4.参考：エラー対策試行錯誤](#3-4.参考：エラー対策試行錯誤)に試行錯誤の内容を列挙しますが，筆者の環境では，

* 環境変数DISPLAY=:0.0を設定する
* c:\users\MyUser\.wslconfigから```guiApplications=false```の設定を削除する  
※設定を削除した後は，```wsl --shutdown```して再起動

の2点の対応で解決しました．

##3-3.Dockerコンテナ上からのGUIアプリ起動

これまで使用していたDockerには環境変数やX11環境の設定は考慮していないので，当然ですが，下記の通りエラーが発生しました．

```
# export DISPLAY=:0.0
# xeyes
Error: Can't open display:
```

環境変数DISPLAYとX11環境(/tmp/.X11-unix)があればよいので，docker runの引数に```-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY```を追加して，Dockerコンテナ上からGUIアプリを起動することができました．

##3-4.参考：エラー対策試行錯誤

```
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:8534): Gtk-WARNING **: 06:02:44.554: cannot open display:
```

他のアプリでも同様か確認(x11アプリで試行)

```
$ sudo apt install x11-apps -y
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:417): Gtk-WARNING **: 06:13:00.458: cannot open display:
$ xeyes
Error: Can't open display:
```

gedit同様にエラーが出た．
[NVIDIA WSL 用 GPU ドライバー](https://developer.nvidia.com/cuda/wsl)のバージョンを更新してみる．

```
$ nvidia-smi.exe
Fri Sep 10 06:15:27 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 465.42       Driver Version: 465.42       CUDA Version: 11.3     |
|-------------------------------+----------------------+----------------------+
| GPU  Name            TCC/WDDM | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
↓
$ nvidia-smi.exe
Fri Sep 10 06:23:48 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.06       Driver Version: 510.06       CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| GPU  Name            TCC/WDDM | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
...
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:26): Gtk-WARNING **: 06:24:52.648: cannot open display:
```

関係なかった．
パッケージをアップグレードしてみる．

```
$ sudo apt upgrade -y
...
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:8407): Gtk-WARNING **: 10:15:52.745: cannot open display:
```

関係なかった．
~/.profile に環境変数DISPLAYを設定する(export DISPLAY=:0.0を追記)．

```
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:8503): Gtk-WARNING **: 10:30:08.404: cannot open display: :0.0
```

関係なかった．
[wslgでGUIを出そうとしたときに"Error: Can't open display: :0"と言われたときの対処法](https://qiita.com/blancshio/items/f2d9b6b885a0ee3ad912)を参考に，/etc/tmpfiles.d/wslg.conf を作成した．

```
$ gedit test.txt
Unable to init server: Could not connect: Connection refused

(gedit:125): Gtk-WARNING **: 09:42:57.859: cannot open display:
```

関係なかった．
[WSLg System Distro](https://github.com/microsoft/wslg#wslg-system-distro)にc:\users\MyUser\.wslconfigに

```
[wsl2]
guiApplications=false
```

を設定するとGUIアプリケーションサポートをOFFにすることができると書いてあり，まさかと思い確認すると，この設定が記述されていた．
何かの作業の際に設定したと思われるが，設定を削除後，```wsl --shutdown```でWSLを一度停止して，再起動するとGUIアプリケーション(geditとxeyes)が起動することが確認できた．
環境設定DISPLAY=:0.0の設定は必要な模様．

#4.さいごに

色々と試行錯誤をしましたが，結局は筆者の過去の取り組みを悔やむ形となりました．
Pythonのmatplotlibからのグラフ出力などのGUI出力も確認ができました（モジュールごとのGUI出力設定は必要）．
参考になる方がおられたら幸いです．

#5.関連リンク

* [Linux 用 Windows サブシステムで Linux GUI アプリを実行する (プレビュー)](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps)
* [[Motherboard] ASUS マザーボードに Windows 11 をインストールする方法は?](https://www.asus.com/jp/support/FAQ/1046215/)
* [Windows 11導入に必要なBIOS/UEFI設定メモ](https://blog.mizarsid.net/2021/07/05/bios-win11/)
* [Windows11 の WSL2 ＋ WSLg で GUI アプリ実行時に発生するエラー「Error: Can’t open display: 0」の対処方法](https://snowsystem.net/other/windows/wsl2-wslg-error-display0/)
* [wslgでGUIを出そうとしたときに"Error: Can't open display: :0"と言われたときの対処法](https://qiita.com/blancshio/items/f2d9b6b885a0ee3ad912)
* [Diagnosing "cannot open display" type issues with WSLg](https://github.com/microsoft/wslg/wiki/Diagnosing-%22cannot-open-display%22-type-issues-with-WSLg)
* [WSL 2: Run Graphical Linux Desktop Applications from Windows 10 Bash Shell "Error E233: cannot open display"](https://stackoverflow.com/questions/61860208/wsl-2-run-graphical-linux-desktop-applications-from-windows-10-bash-shell-erro)
* [WSLg System Distro](https://github.com/microsoft/wslg#wslg-system-distro)
* [Can I use the new WSLg with Docker?](https://www.reddit.com/r/bashonubuntuonwindows/comments/n2nthu/can_i_use_the_new_wslg_with_docker/)