はじめに
ASP.NET CoreのgRPCのテンプレートから新しいプロジェクトを作っただけなのに、protoc-gen-grpc: The system cannot find the path specified
というメッセージが表示され、ビルドが通らない場合の対処方法です。
エラーの内容
コンソールで新しいgRPCのプロジェクトを作成してビルドした場合、次のようなメッセージが表示されprotoファイルのビルドに失敗することがあります。
❯ dotnet new grpc
テンプレート "ASP.NET Core gRPC Service" が正常に作成されました。
作成後の操作を処理しています...
C:\localrepo\Hoge\Hoge.csproj で ' dotnet restore ' を実行しています...
復元対象のプロジェクトを決定しています...
C:\localrepo\Hoge\Hoge.csproj を復元しました (4.08 sec)。
正常に復元されました。
❯ dotnet build
.NET 向け Microsoft (R) Build Engine バージョン 17.1.1+a02f73656
Copyright (C) Microsoft Corporation.All rights reserved.
復元対象のプロジェクトを決定しています...
復元対象のすべてのプロジェクトは最新です。
--grpc_out : error : protoc-gen-grpc: The system cannot find the path specified. [C:\localrepo\sugiyama\Hoge\Hoge.csproj]
ビルドに失敗しました。
--grpc_out : error : protoc-gen-grpc: The system cannot find the path specified. [C:\localrepo\sugiyama\Hoge\Hoge.csproj]
0 個の警告
1 エラー
経過時間 00:00:04.06
原因
このIssueで言及され対応されていますが、Nugetのgrpc_toolsでインストールされるprotc.exe
が非ASCII文字を含んだパス配下に格納されると、protoファイルのビルドに失敗することが原因のようです。
このIssueはこのPRがマージされたとしてクローズされているので、もう少し待てば今回の対応は不要になるかもしれません。少なくとも、2022/09/06時点の最新である2.48.0やPreview版の2.49.0-pre1では対応が必要なようです。
grpc_toolsの場所
grpc_toolsがどこにインストールされているかは次のコマンドで確認できるglobal-packages
配下のディレクトリに保存されます。見事に日本語のディレクトリ配下に保存されていますね。
❯ dotnet nuget locals all --list
http-cache: C:\Users\杉山洋一\AppData\Local\NuGet\v3-cache
global-packages: C:\Users\杉山洋一\.nuget\packages\
temp: C:\Users\杉山洋一\AppData\Local\Temp\NuGetScratch
plugins-cache: C:\Users\杉山洋一\AppData\Local\NuGet\plugins-cache
ユーザー名を英語などで定義すればこの問題は起きませんが、企業で利用している場合などで、AzureADなどのユーザー名が日本語で定義されていると逃れようがないので、global-packages
ディレクトリを非マルチバイトなディレクトリに変更してする必要があります。
対処方法
global-packages
ディレクトリを変更にするには次のような方法があります。
- dotnet コマンドの
--packages
オプションを利用して復元する - OSの環境変数 NUGET_PACKAGES を設定する
- グローバルな Nuget.Config を利用する
- ローカルの Nuget.Config を利用する
OSの環境変数やグローバルな設定ファイルでは他のプロジェクトへの影響が大きいですし、dotnetコマンドを使った解決ではVisual Studioでの作業の時に困るので、今回はプロジェクトディレクトリ(もしくはソリューションディレクトリ)に下記のようなNuget.Configを作成する方法で対応しました。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value="c:\temp\nuget\packages" />
</config>
</configuration>
改めてディレクトリを確認すると、global-packages
が書き換わっているのがわかりますね。
❯ dotnet nuget locals all --list
http-cache: C:\Users\杉山洋一\AppData\Local\NuGet\v3-cache
global-packages: c:\temp\nuget\packages
temp: C:\Users\杉山洋一\AppData\Local\Temp\NuGetScratch
plugins-cache: C:\Users\杉山洋一\AppData\Local\NuGet\plugins-cache
念のため、Nugetのキャッシュをクリアした後に
dotnet nuget locals global-packages --clear
ビルドすると、問題なくビルドできるようになります。
> dotnet build
.NET 向け Microsoft (R) Build Engine バージョン 17.1.1+a02f73656
Copyright (C) Microsoft Corporation.All rights reserved.
復元対象のプロジェクトを決定しています...
復元対象のすべてのプロジェクトは最新です。
Hoge -> C:\localrepo\sugiyama\Hoge\bin\Debug\net6.0\Hoge.dll
ビルドに成功しました。
0 個の警告
0 エラー
経過時間 00:00:07.02
おわりに
Windowsの文化圏にいると忘れがちですが、外から入ってくるツールではまだまだ日本語とかマルチバイトをちゃんと考慮できていないツールのことを気にしないとダメですね。