WSLがエラーコード4294967295で起動しない
Windows TerminalでWSLのUbuntuを開こうとしたところ、このようなエラーが出て起動してくれませんでした。
ネットワーク名が見つかりません。 [process exited with code 4294967295 (0xffffffff)]
ふだんならWindowsにログインしてWindows Terminal開けばアクセスできていました。
Windows側から wsl -l --verbose
で調べてみたところ、どうやらWSLが止まっているもよう。
>wsl -l --verbose NAME STATE VERSION * Ubuntu Stopped 2
エクスプローラで \\wsl$
を開いて見ても、ふだんなら表示されているはずのUbuntuが消えていました。
とりあえずWSLを起動するコマンドを打ってみます。
>wsl -d Ubuntu Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.72-microsoft-standard-WSL2 x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of ...
起動してくれました。
軽く調べてみたところ、WSLのネットワークまわりを変更したときにおこったりすることもあるようですが、直近で特にそういった操作はおこなっていなかったので、何かのタイミングによってこういうことがあるのかも。
Pythonを複数バージョンインストールしているときにwingetでアップデートしてみる
先日WindowsでPythonの環境を作った際、wingetとPythonランチャーで複数バージョンのPythonを使えるようにしてみました。
どうやら最近3.10系の新しいバージョンが出たようなので、自分の環境もアップデートしてみることにしました。
Python Insider: Python 3.10.2, 3.9.10, and 3.11.0a4 are now available
現行バージョン(3.10)のアップデート
winget list
でインストール済のパッケージの一覧を表示すると、新しいバージョンがあるものについては「利用可能」列にそのバージョンが表示されます。
>winget list python 名前 ID バージョン 利用可能 ソース ------------------------------------------------------------------------------------- Python 3 Python.Python.3 3.9.7150.0 3.10.2150.0 winget Python Launcher {7DE12550-BE09-44DD-BDB4-0EC26BA89DAF} 3.10.7644.0 Python 3 Python.Python.3 3.10.1150.0 3.10.2150.0 winget Python 3 Python.Python.3 3.8.10150.0 3.10.2150.0 winget
私の環境にはPython 3.10、3.9、3.8が入っているのですが、どれも利用可能なバージョンとして 3.10.2150.0
と、3.10系の最新バージョンが表示されていました。
一覧上はどの系統もIDが Python.Python.3
となっていますが、この状態でwingetでアップデートするとどうなるのか?
>winget upgrade --id Python.Python.3 複数のインストール済みパッケージが一致する入力条件を検出しました。入力内容を修正してください。 名前 ID ------------------------------------------------------------- Python 3 Python.Python.3 Python 3.9.7 (64-bit) {0f0bf1a5-3ec1-459b-ab7c-916db941f50d} Python 3.10.1 (64-bit) {af822d5e-759c-4e77-9696-3cc835cd54a9} Python 3.8.10 (64-bit) {e9cd241b-9125-4624-9625-ff42d2f3647f}
指定したIDに一致するパッケージが複数あるということで、何やら別々のIDが表示されました。
>winget upgrade --id {af822d5e-759c-4e77-9696-3cc835cd54a9} 見つかりました Python 3 [Python.Python.3] バージョン 3.10.2150.0 このアプリケーションは所有者からライセンス供与されます。 Microsoft はサードパーティのパッケージに対して責任を負わず、ライセンスも付与しません。 Downloading https://www.python.org/ftp/python/3.10.2/python-3.10.2-amd64.exe ██████████████████████████████ 26.9 MB / 26.9 MB インストーラーハッシュが正常に検証されました パッケージのインストールを開始しています... インストールが完了しました
アップデートされたようです。
改めてインストール済Pythonの一覧を表示してみると、Python 3.10系のみアップデートされていました。
>winget list python 名前 ID バージョン 利用可能 ソース ------------------------------------------------------------------------------------- Python 3 Python.Python.3 3.9.7150.0 3.10.2150.0 winget Python Launcher {7DE12550-BE09-44DD-BDB4-0EC26BA89DAF} 3.10.7644.0 Python 3 Python.Python.3 3.10.2150.0 winget Python 3 Python.Python.3 3.8.10150.0 3.10.2150.0 winget >py --version Python 3.10.2
ひとつ前のバージョン(3.9系)のアップデート
先のURLによると3.9系のアップデートも出ているようでしたので、試してみようと思ったのですが。
>winget show --versions python3 見つかりました Python 3 [Python.Python.3] バージョン ----------- 3.10.2150.0 3.10.1150.0 3.10.150.0 3.9.7150.0 3.9.6150.0 3.9.5150.0 3.9.4150.0 ...
2022/2/7時点では、winget用のパッケージとして 3.9.10
は出ていないようでした。
3.10系がでていることもあり、もしかすると3.9系の最新版はwingetに来ないかもしれないのかもと思い、公式サイトからインストーラーを落として入れてみることにしました。
https://www.python.org/downloads/release/python-3910/ からWindows installer (64-bit)をダウンロードして、インストールを実行。
そのあとで、あらためてインストール済のPythonの一覧を表示してみたところ、ちゃんと3.9系のバージョンがあがっていました。
>winget list python 名前 ID バージョン 利用可能 ソース ------------------------------------------------------------------------------------- Python 3 Python.Python.3 3.9.10150.0 3.10.2150.0 winget Python Launcher {7DE12550-BE09-44DD-BDB4-0EC26BA89DAF} 3.10.7644.0 Python 3 Python.Python.3 3.10.2150.0 winget Python 3 Python.Python.3 3.8.10150.0 3.10.2150.0 winget
現行の最新バージョンであればwinget経由でアップデートしていけそうですが、それよりも前の系統については、必要に応じて手動でアップデートしないといけないのかもしれません。
Windows 10で使うランチャーアプリをFlow Launcherにした
macOSではAlfredを使っていましたが、Windows 10でも同じようなコマンド入力式のアプリケーションランチャーを使いたいと思い、いくつか試した結果、最近はFlow Launcherを使っています。
先日、初めてのプラグインを作ってみました。
上の投稿にも書いたのですが、もともと使っていた Hain というアプリの開発が止まってしまったので、乗り換え先を探した結果、Flow Launcherにたどり着きました。
そこで、そのときに候補になったものと選定理由をメモしておこうと思います。
選定にあたっての条件
選定にあたって、個人的に以下のような条件をあげていました。
- プラグインが作れる
- UWPアプリを起動できる
- マルチプラットフォーム
プラグインが作れる
ランチャー自体の機能としては備わっていなくても、あとで追加できるのであれば自分で作っても良いので。
UWPアプリを起動できる
Microsoft Storeでインストールしたアプリを起動できること。
Hainは対応していなかったので、ショートカットを作って特定のフォルダに集め、それをランチャーに呼び出せるようにしていました。
マルチプラットフォーム
ランチャーは自分の中では利用頻度高いアプリなので、WindowsとmacOSで同じ操作感で使えるのであれば、その方が良いかもという考えもありました。
これはプラグインが作れることにも関係していて、せっかく作るのであればmacOSでも使えると良いなと思っていました。
候補と個人的感想
今回試してみたものは以下のような感じ。
※数値は2022/1/30時点
アプリ | Star | Fork | 備考 |
---|---|---|---|
Cerebro | 7215 | 471 | マルチプラットフォーム(Win/mac/Linux) |
ueli | 2222 | 175 | マルチプラットフォーム(Win/mac)、プラグイン機能なし |
Keypirinha | 850 | 20 | プラグイン豊富 |
PowerToys Run | 67,345 | 3,790 | PowerToysの機能の一つ、Woxベース |
Wox | 21,289 | 2,291 | PowerToys Runのベース |
Flow Launcher | 756 | 53 | Woxベース |
Cerebro
Cerebro App – open-source productivity booster with a brain
実はHainを使っているころから目をつけていて、Hainが止まったのを知って、最初はこちらに乗り換えようとしました。
Electronベースでマルチプラットフォーム(Windows/macOS/Linux)で使える点と、JavaScriptでプラグインを作れる(npm経由で配布)点が魅力でした。
当時は個人でmacOSも併用していたので、プラグインを自作したときにWindowsでもmacOSでも使えると便利だなと思い、環境の共通化という観点で良さそうだなと思ったのでした。
ただ、いざ今回乗り換えようとしたところ、最新版の0.4.0は肝心のWindowsビルドに問題があるようで配布されておらず、手元でビルドしてもうまくいかなかったので、導入は断念しました。
ueli
ueli - A keystroke launcher for Windows and macOS
これもElectronベースでWindowsとmacOSに対応しているランチャー。
触ってみたところ、非常に高速に動作するしUWPアプリにも対応しているので良さそうだったのですが、プラグイン機能がなかったので、残念ながら今回は見送り。
要望はあがっているようなので、いずれプラグイン作れるようになったら再度検討しても良いかもとは思っています。
Keypirinha
こちらも機能豊富で、プラグインも作れるので、UWPアプリもプラグインで対応しているので良さそうかなと思ったのですが…
デフォルトのランチャー起動キーバインドが Ctrl + Win + K
だった点は設定で変更できたのでまあ良いのですが、ランチャーに表示された機能を選択する際に Ctrl + n / p
で移動ができなかった点が個人的な操作感として慣れなかったので見送りに。
PowerToys Run
microsoft/PowerToys: Windows system utilities to maximize productivity
PowerToysに付属しているランチャー機能。
そういえばそんなのあったなと思って、いろいろ迷っている間に仮で使ってみたらわりと良かったので、しばらく使っていました。
ただ、まだ公式でプラグインがサポートされていないのですが、ベースになっているWoxというランチャーアプリではプラグイン機能がサポートされているので、それならWoxでも良いかもと思って、Woxを試してみることにしました。
Wox
そんなこんなで、もうこれで決まりかなと思ってWoxをインストールしてみたのですが…
インストールした直後あたりからPCのファンが回る勢いが急激に早くなる症状が発生。
どうやら既知の問題ではあるようで、UWPアプリをインデックス化するときに問題が起きているっぽい感じ。
taking too much cpu resources · Issue #3349 · Wox-launcher/Wox
それで、このIssueのなかで、こっちでは問題でないよ、と名前が出ていたのがFlow Launcherでした。
Flow Launcher
これもWoxをフォークして開発されているもののようで、もしかしたら同じ問題が出るのではとヒヤヒヤしながらインストールしてみましたが、こちらは特にCPUがブン回ることもなく、UWPアプリも実行できました。
操作感は同じくWoxをベースにしているPowerToys Runと近く、かつこちらはプラグイン機能もサポートされていたので、
あと標準機能でゴミ箱を空にするが使えたのも個人的に気に入ったところでした(macOSのAlfredでよく使っていた機能がempty trashなので)。
結論
そんなわけで、今はFlow Launcherを使っています。
プラグインも当初はC#かPythonでの開発でしたが、最近JavaScript/TypeScriptもサポートされたので、裾野が広がってくれるといいな。
デスクトップ上のファイルを掃除するFlow Launcherプラグインを作った
Flow Launcher用のプラグインを初めて作ってみました。
umi-uyura/Flow.Launcher.Plugin.DesktopCleanup
プラグインページにも掲載してもらえました。
Flow Launcherとは
Flow LauncherはWindows用のアプリケーションランチャーです。
以前は Hain を使っていたのですが、いつの間にかリポジトリがアーカイブ状態になっていて、開発が止まってしまっているようでした。
そこで乗り換え先を探していくつかのランチャーアプリを試してみて、個人的に気に入ったので使ってみているのがFlow Launcherです。
wingetでインストールできます。
> winget install "Flow Launcher"
自分でプラグインを作ることができるものを探していて、Flow Launcherは.NET(C#) / Pythonで書くことができます。
※私が2,3ヶ月前に着手したときには上記2つがメインでしたが、最近になってJavaScript/TypeScriptでの開発方法もドキュメントに追加されました。
About Flow's TypeScript/JavaScript plugins
Desktop Cleanupプラグイン
今回作ったのは、デスクトップにあるファイルやフォルダを削除する、もしくはゴミ箱に移動するプラグインです。
私はデスクトップにはゴミ箱以外のファイル等を置かない派なのですが、wingetやChocolateyを使ってアプリケーションをインストールしたりアップデートをするたびにショートカットが作られてしまったりするので、それをサクッと削除したいときに使います。
Flow Launcherを使っている方であれば、ランチャーに pm install desktop cleanup
と入れて実行するか、もしくは設定画面のPlugin StoreからDesktop CleanupのInstallボタンを押すことでもインストールできます。
dc clean
で削除、 dc trash
だとゴミ箱に移します。
ちなみにゴミ箱に入れた場合でも、Flow Launcherで Empty Recycle Bin
を実行するとゴミ箱を空にできるので、いきなり削除するのが怖い人でも安心です。
今回のハマりどころ
Publicユーザーのデスクトップ
単純にデスクトップ上にあるファイル(ショートカット)を削除するだけなので大したことないと思っていたのですが、いざやってみたら削除されない、というかそもそもプログラムからも見えないファイルがあって、その解明に時間を使ってしまいました。
見えないと思っていたのは、実際には全てのユーザー向けにインストールされたアプリのショートカットでした。
これは実体としてはPublicというユーザーのデスクトップ上に存在しており、それが個々のユーザーのデスクトップ上にも表示されるというWindowsの仕組みでした。(たしかXPあたりのころはAll Usersという名前だった気がする)
インストーラですべてのユーザー向けにインストールした場合など、実際にはこのような仕組みになっていたんですね。
このため、自分のデスクトップ上では見えているのに、コマンドプロンプトなどでデスクトップフォルダの中を見た場合には(当然)存在していないということになります。
当初、プログラム上から自分のデスクトップのパス( %USERPROFILE\Desktop
)にあるファイルを削除するようにしていましたが、そうするとPublicユーザーのデスクトップ( %PUBLIC%\Desktop
)にあるものは当然パスに含まれないために消えせん。
最初はなぜ見えないのかわからず、権限の問題?シンボリックリンクの種類?など見当違いの方向を調べていましたが、消せないショートカットのプロパティの場所に表示されているパスを見てようやく気づいた次第です。
基本的にPCは一人でしか使わないですし、デスクトップに何か置かれたらすぐに削除するかどこかに移してしまうこともあって今まで気にしたことがありませんでしたが、今更ながらWindowsのマルチユーザーの仕組みの一端を知りました。
Windows 10でPython環境構築 (wingetとPythonランチャー)
基本的にはPython触るならWSL側にHomebrewとasdfで作った環境を使おうと思いますが、Windows側で何かをするときのために、Windows側にもPython環境を作ることにしました。
まだ何もインストールしていないときの環境。
>where python C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\python.exe >python --version Python
デフォルトで python.exe
が存在していますが、バージョン情報を表示しようとしても python
としか表示されません。
これを実行するとMicrosoft Storeが起動して、ストア版のPythonのページに飛びます。
そこからインストールすることもできますが、ストア版のPythonには制限もあるようなので、Python公式サイトで配布されるインストーラ版を使うことにしました。
参考)
Pythonをインストールする
公式サイトからダウンロードしても良いですが、wingetでもインストールできます。
> winget install -s winget -e --id Python.Python.3
refreshenv
コマンドで環境変数を読み直すと、Python関連のパスが2つ追加されていました。
>refreshenv Refreshing environment variables from registry for cmd.exe. Please wait...Finished.. >set | findstr /i python Path=(中略)C:\Users\<user>\AppData\Local\Programs\Python\Python310\Scripts\;C:\Users\<user>\AppData\Local\Programs\Python\Python310\;(以降、略)
Pythonコマンドの実体を調べてみます。
>where python C:\Users\<user>\AppData\Local\Programs\Python\Python310\python.exe C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\python.exe >where pip C:\Users\<user>\AppData\Local\Programs\Python\Python310\Scripts\pip.exe >where pip3 C:\Users\<user>\AppData\Local\Programs\Python\Python310\Scripts\pip3.exe >where py C:\Windows\py.exe
もともと存在していた python.exe
に加えて、追加されたPATHの方にも python.exe
が見つかりました。
また、複数のPythonのバージョンを切り替えて使えるPythonランチャー(py.exe)もインストールされていることを確認できました。
python
でも py
でも、バージョン情報が出力されることを確認。
>python --version Python 3.10.1 >py --version Python 3.10.1
参考)
PATHは必ずしも通っていなくて良いらしい。
確かに今後別のバージョンを追加したときに混乱しそうなので、いったん以下は環境変数から消して使ってみることにしました。
C:\Users\<user>\AppData\Local\Programs\Python\Python310\ C:\Users\<user>\AppData\Local\Programs\Python\Python310\Scripts\
※このあと3.9を追加インストールする際に、PATHを追加せずにインストールする方法を記載しています。
Pythonランチャー(py.exe)で複数バージョンを切り替えてみる
Pythonランチャーで別のバージョンを使いたい場合は、 py <version>
と使いたいバージョンを指定して実行します。
>py <version> <script> # 最新バージョンで実行 >py -3 <script> # 3系の最新バージョンで実行 >py -3.9 <script> # 3.9で実行
指定したバージョンがインストールされていない場合は、その旨表示されます。
>py -3.9 --version Python 3.9 not found! Installed Pythons found by py Launcher for Windows -3.10-64 * Requested Python version (3.9) not installed, use -0 for available pythons
試しに -3.9
を指定してみると上記のようなメッセージが表示されましたので、追加で3.9をインストールしてみます。
wingetでインストールできる過去のバージョンは winget show --versions <query>
で取得できます。
>winget show --versions --id Python.Python.3 見つかりました Python 3 [Python.Python.3] バージョン ----------- 3.10.1150.0 3.10.150.0 3.9.7150.0 3.9.6150.0 3.9.5150.0 ...
3.9系の最新である 3.9.7150.0
をインストールするため、wingetに --version
オプションを付けてバージョンを指定して実行します。
>winget install -s winget -e --id Python.Python.3 --version 3.9.7150.0 --override PrependPath=0
また --override PrependPath=0
を付けることで、環境変数PATHへの追加されずにインストールすることができます。
このときインストーラの画面が開くので、 Add Python 3.9 to PATH
のチェックが外れていることを確認して、「Install Now」を選べばOKでした。
インストール後に python
の所在を確認してみます。
>where python C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\python.exe >py --version Python 3.10.1 >py -3.9 --version Python 3.9.7
PATHは追加されていませんが、 py -3.9
で3.9版のバージョンが表示されました。
現在の環境にインストールされているバージョンを一覧表示するには --list
もしくは --list-paths
を使います。
>py --list Installed Pythons found by py Launcher for Windows -3.10-64 * -3.9-64 >py --list-paths Installed Pythons found by py Launcher for Windows -3.10-64 C:\Users\<user>\AppData\Local\Programs\Python\Python310\python.exe * -3.9-64 C:\Users\<user>\AppData\Local\Programs\Python\Python39\python.exe
*
が付いているバージョンがデフォルトで使われるもので、これは設定で変更することができます。
参考)
Pythonランチャー+venv
Pythonランチャーでvenvが使えるかを確認します。
>py --version Python 3.10.1 >py -3.9 -m venv .venv
デフォルトが 3.10
の状態で、 3.9
を指定してvenv環境を作ります。
>.venv\Scripts\activate (.venv) >py --version Python 3.9.7
activate
すると、何も指定しないで実行した py
が返すバージョンが 3.9
になりました。
(.venv) >where python C:\Users\<user>\workspace\python\pyexe-test\.venv\Scripts\python.exe C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\python.exe
作成したvenv環境の python
が優先されるようになっていました。
(.venv) >py --list-paths Installed Pythons found by py Launcher for Windows (venv) C:\Users\<user>\workspace\python\pyexe-test\.venv\Scripts\python.exe * -3.10-64 C:\Users\<user>\AppData\Local\Programs\Python\Python310\python.exe -3.9-64 C:\Users\<user>\AppData\Local\Programs\Python\Python39\python.exe
py --list-paths
してみても、venv環境が追加されていました。
最新版以外を使う場合は、都度使うバージョンを指定する必要がありますが、いちいち切り替えなくて済むという点では、pyenv方式よりPythonランチャーの方が使い勝手は良いのかも。
とりあえず、Windows側でPython使うときはPythonランチャーを意識して使ってみます。
参考
Chocolateyをアップデートしたらexe.oldへのアクセス拒否が出た
少し前ですが、Chocolateyにアップデートが来ていたのでアップデートしたのですが、その後使おうとしたときに、何やらアクセス拒否されたというエラーが出ました。
>choco Chocolatey v0.11.3 Please run 'choco -?' or 'choco <command> -?' for help menu. This is try 1/3. Retrying after 300 milliseconds. Error converted to warning: パス 'C:\ProgramData\chocolatey\choco.exe.old' へのアクセスが拒否されました。 This is try 2/3. Retrying after 400 milliseconds. Error converted to warning: パス 'C:\ProgramData\chocolatey\choco.exe.old' へのアクセスが拒否されました。 Maximum tries of 3 reached. Throwing error.
このエラー自体は gsudo
付きで choco
コマンド単発で呼び出すだけで解消されました。
>gsudo choco Chocolatey v0.11.3 Please run 'choco -?' or 'choco <command> -?' for help menu. >choco Chocolatey v0.11.3 Please run 'choco -?' or 'choco <command> -?' for help menu.
原因については想像ですが、以前は choco
コマンドを使うときは管理者権限のコマンドプロンプトを起動して使っていましたが、最近は gerardog/gsudo を使って gusodo choco upgrade chocolatey
のように管理者権限付きで実行するようにしていたのですが、もしかするとその違いによって、アップデート処理の中で、権限が適用されなくなってしまう処理などがあるのかもと推測しています。
実際にアップデートしてから、このエラーに遭遇するまで間があいていたこともあるので、またChocolateyのアップデートが降ってきたら確認してみようと思い、とりあえずメモしておきます。
WindowsのNode.jsバージョン管理をNodistからfnmに変えてみる
これまでWindowsでNode.jsのバージョン管理はNodistを使っていましたが、改めて環境構築を構築をしていくにあたってMicrosoftのドキュメントを眺めていたところ、Nodist以外にもそういったツールがあることを知りました。
WSL2(Linux)向けの方で掲載されているパッケージ管理ツールのほうが多いですが、その中のいくつかはマルチプラットフォームで、ネイティブWindowsでも使えそうなものもあります。
2020 年ではもう使えない Nodist はアンインストールする (Windows)
この記事に触発されたというわけでもないのですが、最近WSLを触り始めたこともあり、Windows/Mac/Linux(WSL)で同じように使えるツールにしておけると迷うことも少ないかなと思い、Nodistから乗り換えてみることにしました。
マルチプラットフォームなNode.jsバージョン管理ツール
Windowsをサポートしているマルチプラットフォームなものをピックアップしてみました。
それぞれのリポジトリや公式サイトを眺めてみての個人的に気になった点を挙げてみました。
名前 | 対応プラットフォーム | ポイント |
---|---|---|
nvm-windows | Windows | ・ nvm のWindows版、なのかと思いきやが互換性があるわけではないみたい ・Go製 ・自動バージョン切り替えはない |
nvs | Windows/Mac/Linux | ・VSCode連携あり ・コマンドプロンプトのサポートが弱い(PowerShellだと自動バージョン切り替えができる) ・wingetでインストールできる |
Volta | Windows/Mac/Linux | ・Rust製、速度重視 ・他のツールと若干使い方が違う印象 ・package.jsonに使うNodeのバージョンなどを記録する ・wingetでインストールできる |
fnm | Windows/Mac/Linux | ・Rust製、こちらも速度重視 ・自動バージョン切り替えに対応 |
(番外)asdf-nodejs | Mac/Linux | ・asdf公式 ・自動バージョン切り替えに対応 |
Nodistも備えていましたが、プロジェクトディレクトリにある .node-version
や .nvmrc
などを参照して使うNodeのバージョンを切り替えてくれる機能は欲しいところ。
Linux(WSL)とMacだけで考えれば asdf公式のNode.jsプラグイン が自動切り替えにも対応していて良さそうではありますが、Windowsでも使えるものからとなると、nvs、Volta、fnmあたりが選択肢になりそうです。
(nvm-windowsは紛らわしいですが、本家nvmのクローンということではないらしい。コマンドも微妙に使い方が違っていたりと今回の目的に合わないため選外)
その中でnvsとVoltaについては以下のような点が自分的に気になったので、今回はfnmを使ってみることにしました。
- nvsはコマンドプロンプト主体で考えると切り替え機能がサポートされない
- Voltaは他のツールと違ってpackage.jsonにバージョンを記録する(業務利用を考えたときに、自分の会社ではそのあたりのツールが統一されているわけではないため、自分のためだけに編集はしにくい)
Nodistをアンインストールする
まずは既存環境のNodistを削除する手順で、この点については先のNodistアンインストールの記事がとても参考になりました。
2020 年ではもう使えない Nodist はアンインストールする (Windows)
以下、その記事の手順をなぞったときのメモ。
- Nodistのアンインストール
- 記事ではコントロールパネルから実施していましたが、私はChocolateyでインストールしていたので、
choco uninstall nodist
で削除しました
- 記事ではコントロールパネルから実施していましたが、私はChocolateyでインストールしていたので、
- Nodistインストール先フォルダの削除
- 確かに残っていて、npmの各バージョンが残っていたと1GB近くありました
- npm-cacheフォルダの削除
- これも残っていて、3.5GBもありました…
- .npmrcの削除
- これについては、私の環境ではNodistに関するもの以外の設定もあったので、該当行のみ削除してファイル自体は残しました
fnm (Fast Node Manager)をインストールする
インストールは簡単で、 Releases · Schniz/fnm から利用しているプラットフォーム向けのバイナリをダウンロードして、PATHが通っているところに置くだけでも使えます。
またWindows向けにはChocolateyからもインストールすることもできるので、私はこちらの方法を使いました。
# 要管理者権限 > choco install fnm -y or # Use gsudo > gsudo choco install fnm -y
gerardog/gsudo を使うと、わざわざ管理者権限でターミナルを開き直さなくても良いので便利です。
コマンドプロンプト向けシェルセットアップ
さてインストールが完了したら、使っているシェルに合わせてfnmを使うための初期化処理を設定する必要があります。
Bash向けなどは .bashrc
に eval "$(fnm env)"
を追記すれば良いという感じで非常に簡単なのですが、Windows特にコマンドプロンプト向けのセットアップは一筋縄ではいきませんでした。
Windows Command Prompt aka Batch aka WinCMD
コマンドプロンプトを起動したときに何か処理をおこないたい場合、レジストリの HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor
の AutoRun
キーに設定することで実行させることができます。
fnmのREADMEによれば、そこに以下のコマンドを登録することでセットアップがおこなわれるようです。
FOR /f "tokens=*" %i IN ('fnm env --use-on-cd') DO CALL %i
ただ自分の場合は、他にも初期化処理でやりたいことがあったので、バッチファイルを登録して、その中で上記の処理を呼び出すことにしました。
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor] "AutoRun"="C:\Users\<user>\mystartup.cmd"
ところがこれがうまくいかず、コマンドプロンプトを起動すると i was unexpected at this time.
というメッセージが表示されました。
これはfnmのREADMEにも対処法が書かれていますが、原因としてはバッチファイルの中で FOR
を使う場合の変数の書き方を %i
ではなく %%i
としなければいけないからでした。
よって以下のように書き換えます。
FOR /f "tokens=*" %%i IN ('fnm env --use-on-cd') DO CALL %%i
これでうまくいくかと思いきや、確かに先のメッセージは出なくなったものの、今度は処理が戻ってこない状態になりました。
いろいろ調べた結果、次のことがわかりました。
for /f
はサブプロセス実行時にcmd.exe
を起動するため、そこでまたAutoRunが走ってしまうことで無限ループに陥る可能性があるcmd /d
を指定することでAutoRunを無効にできるが、for
の中では効かないっぽい
参考:
- batch file - CMD AutoRun hang - Stack Overflow
- cmd - Make batch FOR /F ignore Registry AutoRun - Stack Overflow
- 汝、コマンドプロンプトを愛せよ - Qiita
fnmのREADMEにはCmderというターミナルアプリの起動スクリプト機能を使うことで回避する方法が載っていますが、これだとWindows Terminalが使えないので個人的にはイマイチ。
そこで起動バッチのなかで多重実行を防ぐような仕組みを入れたところ、無限ループにならずに初期化処理が実行できるようになりました。
具体的には初回実行時にある環境変数に値を入れるようにして、実行時にその環境変数に値がある場合はそこで処理を終了するというもので、以下のような実装です。
mystartup.cmd
@ECHO OFF IF "%MYSTARTUP_INIT%"=="OK" ( EXIT /b ) ECHO ... Running startup script SET MYSTARTUP_INIT=OK REM Setup fnm FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z ECHO ... Complete startup script
これでfnmを使うことができるようになりました。
基本的な使い方
# インストール可能なバージョンの一覧 > fnm ls-remote v0.1.14 v0.1.15 v0.1.16 ... # 省略 v16.8.0 v16.9.0 v16.9.1 v16.10.0 # 指定したバージョンをインストール > fnm install v16.10.0 Installing Node v16.10.0 (x64) # インストール済のバージョン一覧 > fnm ls * v14.17.6 * v16.10.0 default * system # 現在のデフォルトで使われるバージョン > fnm current v16.10.0 # デフォルトバージョンの設定 > fnm default v14.17.6 > node -v v14.17.6
自動バージョン切り替えを試してみる
あらかじめ、16系と14系をインストールしておきます。現在のデフォルトは16。
> fnm install 14 Installing Node v14.17.6 (x64) > fnm list * v14.17.6 * v16.10.0 default * system
わかりやすく node14 と node16 フォルダを作り、それぞれに対応するバージョンを書いた .node-version ファイルを配置します。
> type node14\.node-version v14 > type node16\.node-version v16.10.0
それぞれのフォルダに移動してみます。
> cd node14 Using Node v14.17.6 > fnm current v14.17.6 > node -v v14.17.6 > cd ..\node16 Using Node v16.10.0 > fnm current v16.10.0 > node -v v16.10.0
node14 フォルダに入るとカレントバージョンが14に、 node16 フォルダに移動するとカレントバージョンは16になりました。
.node-version ファイルの内容に合わせて使うNodeバージョンが切り替わってくれることが確認できました。
※2021/10/06追記
プロジェクトのバージョン指定に使うファイルは .node-version だけでなく、nvm由来の .nvmrc を使うツールもあります。
fnmは .nvmrc にも対応しているようだったので試してみたところ、同じようにバージョンが切り替わってくれました。
> type node14\.nvmrc 14 > type node16\.nvmrc v16.10.0 > node -v v14.17.6 > cd node16 Using Node v16.10.0 node16> fnm current v16.10.0 node16> node -v v16.10.0 node16> cd ..\node14 Using Node v14.17.6 node14> fnm current v14.17.6 node14> node -v v14.17.6
おわり
Rust製で売りの一つにスピードとあるだけに、たしかに速い気がします。