WSL で Windowsネイティブな.exeを実行する

この記事は約8分で読めます。

WSL は大変便利で大抵のことはその中で完結できますが、ときどき Windows側の .exe を使いたくなるときがあります。

例えばUSB接続したAndroid端末を制御するにはAndroid デバッグツール adb  を使います。ですがWSLのadbを実行してもデバイスを見つけられず下記のようなエラーになります。

$ adb devices
adb: no devices/emulators found

このような場合はWSL内のつーるでは操作は難しいので素直にWindows側のadb.exeを実行したほうが楽です。単純に使うだけなら.exeをWSLから実行すればいいのですがいくつかはまりポイントがあります

そこで今回は Windows ネイティブの adb.exe を例に WSL からWidowsの .exe を使うコツを説明します。
今回は adb.exe を例にしていますが、別のツールでも基本的に一緒のはずです。
是非参考にしてください。

スポンサーリンク

Windows 用の. exe ダウンロード

まずなにはともあれ .exe が必要です。adbの場合は、下記の Windows のPlatform tools をダウンロードします。
下記のサイトから入手できます。

SDK Platform-Tools リリースノート  |  Android Studio  |  Android Developers
Android SDK Platform-Tools は Android SDK 用のコンポーネントです。

platform-tools-latest-windows.zip をダウンロードしたら、任意のフォルダに展開します。
その中にはadb.exe や fastboot.exe が含まれているはずです。

奥場所はどこのフォルダでもいいのですが、Program Files のようなフォルダ名にスペースがある 正気を疑うネーミングの ところは避けたほうがよいです。今回は c:\Programs\platform-tools\ に置いたことにします。エスケープが面倒なのでスペースをフォルダ名、ファイル名に入れないほうが幸せになれると思います。

さらにWindows 環境変数のPATHにも設定しておきます。下記の記事が参考になるかと思います。

【Windows 11対応】Path環境変数を設定/編集して、独自のコマンドを実行可能にする
Windows 10やWindows 11でよく使うコマンドやツールなどがあるなら、それらをまとめて1つのフォルダに保存しておき、そのパスを「Path」という環境変数に追加しておくとよい。Path環境変数をGUIで設定/編集する手順と注意点...
スポンサーリンク

WSL のパス設定

WSL はデフォルトで Windows 側のパス設定を引き継ぐ仕様なので特に何もせずとも adb.exe が使えるはずです。
下記のように which コマンドで adb.exe が見つかればOKです。

$ which adb.exe
/mnt/c/Programs/platform-tools/adb.exe

もし使えない場合は .bashrc などで PATH 変数に追記してください。
今回の例だと下記のように記載すれば良いです。

PATH=$PATH:'/mnt/c/Programs/platform-tools/'
スポンサーリンク

文字コード変換

adb.exe は Windowsの住人なので改行が LF でなく CRLF です。そのため WSL 側から実行してパイプに渡したりすると意図しない挙動をすることがあります。
たとえば adb devices の結果から末尾の空行を削除しようと下記のように tr をつけても削除されません。5行目に空行が入ったままですね。

$ adb.exe devices | tr -s "\n"
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device

$

そこで文字コード変換するために nkf を導入します。apt でインストールできます。

$ sudo apt install nkf

下記のように nkf をパイプでつなげれば改行文字をCRLF → LFにできます。 オプション -Lu が改行をLFにするオプションです。 ちなみに -w はUTF8への返還です。

$ adb.exe devices | nkf -Lu -w | tr -s "\n"
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device
$
スポンサーリンク

環境変数の共有 WSLENV

下記の例のように複数のデバイスが接続されている場合、任意の1つを指定する必要があります。

$ adb.exe devices
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device

指定しないと下記のように、複数のデバイスがあると怒られてしまいます。

$ adb.exe shell whoami
adb.exe: more than one device/emulator

デバイス指定の1つの方法として -s オプションでシリアルを指定する方法があります。

$ adb.exe -s HOGEHOGE01 shell whoami
root

これでもいいのですが毎回 -s をつけるのは面倒です。
adb のヘルプを見ると下記の環境変数があると説明があります。


$ANDROID_SERIAL serial number to connect to (see -s)

ですが下記のようにしてもうまくいきません。

$ ANDROID_SERIAL=HOGEHOGE01 adb.exe shell whoami
adb.exe: more than one device/emulator

これは adb.exe がWindowsの住人なので WSL の環境変数の効果がないためです。
そこで下記のように WSLENV も設定します。WSLENVを設定すするとその設定が Windows 側にも環境変数が共有され期待通り動作します。

$ export WSLENV=ANDROID_SERIAL:HOGEHOGE01
$ export ANDROID_SERIAL=HOGEHOGE01
$ adb.exe shell whoami
root

WSLENV の詳細下記を参照してください。
https://learn.microsoft.com/ja-jp/windows/wsl/filesystems#share-environment-variables-between-windows-and-wsl-with-wslenv

スポンサーリンク

PATH形式変換 wslpath

Windowsの.exeに引数を渡すときはパスの形式に注意が必要です。WSL 側では /mnt/c/Programs/platform-tools/ という表記の場合、Windows側では C:\Programs\platform-tools\ となります。
なのでWindowsの住人であるadb.exeに、下記のようなWSL(というかUNIX/Linux)のパス形式で渡すとエラーになります。

$ adb.exe push /mnt/c/User/username/Download/hoge.bin /data/

これを解決するのが wslpath です。例えば下記のように-w オプションで渡すとWindows形式に変換してくれます。

$ wslpath -w  /mnt/c/User/username/Download
C:\Users\username\Downloads 

これを利用して下記のようにすると正しく adb.exe が hoge.bin のパスを認識してくれます。

$ adb.exe push $( wslpath -w /mnt/c/User/username/Download/hoge.bin ) /data/
スポンサーリンク

WSL と Ubuntuの共存

ここまでくると普通のLinuxとWSLとで同じスクリプトを共有したいという要望が出てくるかもしれません。
下記にその例を書いておきます。ポイントはかきの3つです。

* uname -r に microsoft が含まれればWSL、なければ普通のLinux
* WSLENVで環境変数を共有
* PATHはwslpathで変換

# adb パス設定
if { which abd || which abd.exe } > /dev/null ; then
    ADB=$(which abd || which abd.exe)
fi

# WSLの環境変数をWindowsに共有する設定
ANDROID_SERIAL='hogehoge'
export WSLENV=ANDROID_SERIAL:${ANDROID_SERIAL}
export ANDROID_SERIAL=${ANDROID_SERIAL}

# WSL のときだけWidows形式にパス変換
# WSL は uname -r が 5.15.153.1-microsoft-standard-WSL2のように microsoft が含まれる
DATA=/mnt/c/User/username/Dowload/hoge.bin
${ADB} push $( [[ "$(uname -r)" == *microsoft* ]] && wslpath -w "${DATA}" || echo "${DATA}") /data/
スポンサーリンク

まとめ

今回は adb を例に、 WSL からWindowsネイティブの.exeを使う方法を説明しました。

* 改行コードに注意する
* uname -r に microsoft が含まれればWSL、なければ普通のLinux
* WSLENVで環境変数を共有
* PATHはwslpathで変換

がコツです。ぜひご活用ください。

コメント