• 作成:

2023年11月14日のWindows Updateに含まれるWSLgの更新でKeyhacからwslg.exeが起動できなくなる問題への対処

問題

2023年11月の「Windows Update」、AI機能「Copilot in Windows」などの展開を拡大 - 窓の杜で何かしら問題が発生する可能性は高かったのですが、セキュリティフィックスが含まれていたので仕方なく即座にアップデートしました。

Keyhacによる、 wslg.exe経由でEmacsを起動する設定が動かなくなりました。

その設定は最終的に、

keymap.ShellExecuteCommand(None, com, param, "", swmode="maximized")()

を呼び出すようになっており、引数を埋めると以下のようになります。

keymap.ShellExecuteCommand(None, "wslg.exe", "--cd ~ -d Ubuntu -- emacs", "", swmode="maximized")()

これが動かなくなりました。以下のようなエラーになります。

Traceback (most recent call last):
  File "../ckit\ckit_threadutil.py", line 231, in run
  File ".\keyhac_keymap.py", line 2161, in jobShellExecute
FileNotFoundError: [WinError 2] 指定されたファイルが見つかりません。

Emacsが悪いとかparamsが悪いとかではなく、とにかくwslg.exeが見つかりません。

C++部分の共有ライブラリとかに破壊的変更があったのかと思いましたが不発。

wslg.exeをPowerShellとかから起動すると動くようです。謎。

原因

Update the path of wslg.exe for the new MSI package. by benhillis · Pull Request #1124 · microsoft/wslg で入った変更を見る限り、本物のwslg.exeが入った場所が変わったようです。

対処

本当はPRに含まれているようにレジストリの値を見る必要があると思いますが、大抵の環境なら以下のように本物のwslg.exeを参照するように設定すれば動きます。

def program_files(*pathsegments: str) -> WindowsPath:
    """`C:/Program Files/`以下を単純に参照します。"""
    # Keyhacが現状32bitで動いているため、64ビット版のディレクトリを指してくれるように指定します。
    return WindowsPath(os.environ["ProgramW6432"], *pathsegments)
keymap_global["W-n"] = run_or_raise(
    keymap,
    check_func=check_func_emacs,
    command=str(program_files("WSL", "wslg.exe")),
    param="--cd ~ -d Ubuntu -- emacs",
)

報告

動かないwslg.exePATHにあるのは罠すぎるので、とりあえず原因はさっぱり分からないのですがissueとして建てておくことにしました。

C:\Windows\System32\wslg.exe cannot be called from programs via Python and C++ · Issue #1143 · microsoft/wslg