WSL2で（WSL1でも！）GUIアプリを起動

WSL2では今後GUIに対応する予定なので、何も考えずともGUIアプリが起動できるようになる筈である（WSLgと言う名称らしい。[ここ](https://zenn.dev/suisuiso/articles/eb6796f68324cd)とか参考）。

---
【2022/12/3追記】
Windows11は勿論Windows10でもWSLgが使えるようになりました！ストア版WSLにアップデートすれば使えるようになります。Command Prompt或いはWindows PowerShellで
```wsl --update```
とするだけでO.Kです。以下参照。

https://qiita.com/y-tsutsu/items/6bc65c0ce4d20a82a417

https://qiita.com/murasuke/items/5bbb4fb191bbfe537c8c

https://qiita.com/ilain/items/8185078f719e1965b260

https://forest.watch.impress.co.jp/docs/news/1458044.html

https://www.itmedia.co.jp/news/articles/2211/24/news075.html

https://japan.zdnet.com/article/35196482/

https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps?source=recommendations

~~なのでWSLでGUIアプリを使う目的での以下MobaXtermは要らない子になってしまいました。。。~~
でも一応以下記事は残しておきます。

要らない子と思われたMobaXtermですが、必要なケースがあります。例えば、会社のPCへのWSLのインストール等、WSL2だとネットワークでは許されない場合がある。WSL2は別IPで仮想ホストとして扱われるからだろうか。その場合WSL1にする必要がある。WSL1であればWindowsと同一IPアドレスで、Windowsマシンとみなされ問題ない。その場合通常であればX windowのGUIアプリは立ち上げられないが、以下、MobaXtermでWSL1を立ち上げる事によりGUIアプリを使う事ができる。

---
~~しかし現状ではまだ対応できていない。~~ なのでWindowsにVcXsrvのようなXサーバをインストールして、WSL2側でDISPLAYにローカルマシンのIPアドレスを設定するやり方を紹介している記事がたくさんある。いずれの記事でもDISPLAYに設定するIPアドレスの取得方法として、`cat /etc/resolv.conf`か`ip`コマンドでのやり方を紹介している。しかし私の環境ではこの方法ではWSL2側のIPアドレスしか取って来れず、なぜかうまく動かなかった。半ば諦めかけながら何か別の方法はないかと探していた所、簡単にできる方法を見つけたのでここに紹介しておく。
ここではVcXsrvは使わずMobaXtermと言うXサーバが付属したターミナルソフト（みたいないろいろな物が入った凄い何か）を使う。ターミナル立ち上げと同時にXサーバも自動で立ち上がり大変便利なので断然こちらをお勧めする。

#### 1. MobaXtermをインストール
まずここからダウンロードしてインストール

https://mobaxterm.mobatek.net/download-home-edition.html

#### 2. MobaXtermを立ち上げてWSLに接続
MobaXtermのSessionに最初からWSLのアイコンがあるのでそこをクリック。
そして以下の設定をする。
Basic WSL setting -> Run method : Localhost connection
![MT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471497/65fd4a57-4c08-1705-dc65-dbce3e438aaa.png)
そしてOK。

#### 3. Xサーバへのリモートアクセスをfullに設定
Settings->X11タブに行ってX11 remote accessの項目でfullを選択

#### 4. GUIアプリを起動
あとは好きなGUIアプリを起動するだけ。

```bash:例
$ xeyes
```

#### 
以上を設定すれば次回以降はMobaXtermのWSLターミナルを起動するだけで特に何も気にする必要なくWSL2で（WSL1でも！）GUIが使える。SessionsにWSLのアイコンが出来ているのでお好みで右クリックでデスクトップにショートカットを作ったり、タスクバーにピン止めしておくと良い。
VcXsrvでやるよりずっと簡単で便利なのでこのMobaXtermを使った方法を是非ともお勧めする。私はこのMobaXtermを知らなかったのだが他にもSSHでのリモートホストに接続してXサーバでGUIアプリを起動できたりMSYS2みたいWindowsのBashターミナルがあったりその他いろいろな事ができてなんだかすごい。無料でも十分の機能が使える。

---

#### 以前やってた方法（DISPLAYにWindows側のIPアドレスを設定）
以下以前やっていた方法です。Windows側の設定が変わったのか、MobaXtermの設定が変わったのか、Firewallの設定が変わったのか良く分かりませんが、私の環境では一時期この方法ではうまく行かなくなりました。
MobaXtermの新しいバージョン（20.5以上）であれば2.のRun methodを選択すればよいので今はこの方法は使っていませんが、VcXsrv等他のXserverを使う場合には依然有効なのでメモとして残しておきます。

##### a. WSL2の.bashrcで設定
~/.bashrcに以下を書く

```bash:~/.bashrc
export DISPLAY=`hostname | xargs dig +short | grep 192.168.`:0.0
```
そしたら`source ~/.bashrc`でこれを適用。

##### b. MobaXtermで設定
或いは.bashrcでは設定せずMobaXtermで設定する。
->SessionsにできたWSLアイコンを右クリック
　　->Edit session
　　　　->Basic WSL SettingsのAdvanced WSL Settingsにある
　　　　　Execute the following commands at startup:
に同じコマンドを書いておく。そうすると.bashrcと異なりMobaXtermで立ち上げた場合にのみDISPLAYの設定がされる。

この例では`hostname`でコンピュータ名を調べて`dig`でそのIPアドレスを調べている。コンピュータ名が分かっていれば`hostname`は使わなくて決め打ちでも良い。`dig`ではWindows側とWSL2側の両方のIPアドレスが表示されるのでWindows側のものを取ってくる。`dig`の代わりに他にも`nslookup`や`host`コマンド或いは`ipconfig.exe`と`sed`や`awk`を駆使しても良いだろう。多くの記事で紹介されている`/etc/resolv.conf`や`ip`コマンドでは私の環境ではWSL2側のIPアドレスしか調べられずうまく行かなかった。
コメントで教えてもらった情報によるとWSL2側のIPアドレスではWindowsから見てファイアウォールの外とみなされるのでファイアウォールに穴を開ける等の設定をしないといけない。殆どの記事で紹介されているやり方はその方法の様だ。それに対してWindows側のIPアドレスであればファイアウォールの設定は不要となる。

---

#### ドメインネームを使ってWindowsのホスト名をDISPLAYに設定
~~上記のようにWindows側のIPアドレスを調べるのにいろいろ苦労してましたが、IPアドレスを調べなくても`<Host Name>.mshome.net`でWindows側のホスト名を指定できるそうです。~~

https://qiita.com/taichi-ishitani/items/b627e31a97fef24c6ee4

```bash:
export DISPLAY=`hostname`.mshome.net:0.0
```
嘘でした。`<Host Name>.mshome.net`で参照されるのはWSL2側のIPアドレスでした。
なのでWSL2側のIPアドレスを設定してGUIアプリが動かない場合にはこの方法でも同様です。Windows側のIPアドレスを設定する必要があります。
因みに`<Host Name>.local`も同様にWSL2側のIPアドレスを参照します。

---

#### 最近見つけた別のApp
最近このFreeアプリを見つけた。

https://opticos.github.io/gwsl/

その名もGWSL。今後使えるようになるMicrosoftご謹製のWSLgと似ていてパチモン臭くて紛らわしい。
これもVcXsrvを使っているようだがマニュアルで立ち上げ、立ち下げをしなくていいみたい。誰か使ってみて。

少し使ってみたらこれもWSL2側のIPアドレスを自動で設定するみたいで、私の環境ではそのままでは使えませんでした。なのでやはりMobaXtermで以前やっていた様に以下の様にWindowos側のIPアドレスを設定する必要がありました。

```bash:~/.bashrc
export DISPLAY=`hostname | xargs dig +short | grep 192.168.`:0.0
```

以下の記事でGWSLの使用を紹介しています。

https://qiita.com/1024xx4/items/45a5cce13eafa17ca6f1

---

#### 参考
[Quiita - WSL2のGUI設定でつまずいたところ](https://qiita.com/baibai25/items/5841b0592727893d960f%E3%80%80)
[Quiita - WSL2でGUIをやりたいメモ](https://qiita.com/ChujoHiroto/items/38d665eb61ddf20c0ab3)
[Quiita - WSL2におけるVcXsrvの設定](https://qiita.com/ryoi084/items/0dff11134592d0bb895c)
[MobaXterm を ssh/mosh/X11 クライアントとして使う（Windows）](https://qiita.com/mkasahara/items/c029154b5436913b20e0)
[MobaXtermを使いBash On Windowsで簡単にX11を使う](https://qiita.com/nullsnet/items/716c40fba707c3aafc1a)
[WSL2のX-ServerでGUI表示する際に「export DISPLAY=:0.0」が効かない](https://odaryo.hatenablog.com/entry/2020/01/08/114846)
[Quiita - MobaXtermを使ってWSLのmatplotlibを描画する](https://qiita.com/tart/items/bae14b03ee82cda035bc)