Visual Studio でソリューションを開いた直後、ステータスバーは「準備完了(Ready)」なのに、ビルド/リビルド/クリーン/デプロイ/デバッグ開始が「Build started…」で止まって進まない――。この症状は「裏で何かが待っている」ことが多く、いま何をしているかを可視化できれば、原因特定と復旧が一気に早まります。
「Ready」でも内部は忙しいことがある
ステータスバーの「準備完了(Ready)」は、“UI が入力を受け付けられる状態”を示しているだけで、バックグラウンド処理が完全に終わったことを保証しません。特に最近の Visual Studio は、ソリューションを開いたあとに多くの処理を裏で走らせます。これらが詰まると、見た目は「Ready」でも、ビルドやデバッグ開始が裏処理待ちになり、出力が「Build started…」のまま止まることがあります。
- 設計時ビルド(Design-time build):IntelliSense や参照解決のために、裏で MSBuild が走る
- NuGet パッケージの復元(restore):ネットワーク/プロキシ/証明書/キャッシュの影響を受けやすい
- テスト探索(Test discovery):テストフレームワークがプロジェクトをスキャンする
- Git / ソース管理の状態更新:大規模リポジトリやサブモジュールで時間が延びる
- インデックス作成(検索・参照)やコード解析サービス(Roslyn / ServiceHub など)の初期化
重要なのは、Visual Studio 内部の“タスク待ち”なのか、OS レベル(ファイル/ネットワーク/セキュリティ製品)で待たされているのかを切り分けることです。切り分けができれば、対策は一気に具体化します。
最短で状況を掴むための全体像
調査は「表示(Visual Studio)」「ログ(Visual Studio)」「監視(Windows)」の三段構えが効きます。まずは、どこを見れば何が分かるかを整理します。
| 観点 | 主な手段 | 分かること | 向いている状況 |
|---|---|---|---|
| 表示(VS) | 出力ウィンドウの詳細化、ステータスバー周辺のタスク表示 | どのターゲット/タスク/拡張が処理中かの手掛かり | 「Build started…」直後で止まる、原因の見当が付かない |
| ログ(VS) | ActivityLog.xml | 拡張機能例外、パッケージ読み込み失敗、内部エラー | UIは動くのに特定操作で固まる/再現が一定 |
| 監視(Windows) | ProcMon、タスクマネージャー、リソースモニター | ファイルロック、アクセス拒否、存在しないパス参照、ネットワーク待ち | CPUが低いのに止まる/I/O待ちっぽい/社内環境で起きる |
出力を「見える化」する(ビルド冗長度の設定)
最初にやるべきことは、ビルド中の情報量を増やすことです。既定の出力は情報が少なく、どこで止まっているかが見えません。冗長度を上げると、停止直前の手掛かりが出やすくなります。
設定手順
- [ツール]→[オプション]→[プロジェクトおよびソリューション]→[ビルドと実行]
- 「MSBuild プロジェクトのビルド出力の詳細度」を Detailed(詳細) または Diagnostic(診断) に変更
- ビルド中は [出力]ウィンドウで「ビルド」を選択し、最後に出た行(止まる直前)を確認
「Diagnostic」はログが大量になりますが、“最後に実行されているターゲット/タスク名”が取れるだけで価値があります。例:ファイルコピーで止まっているのか、カスタムターゲットが外部コマンド待ちなのか、などが読み取れます。
出力ウィンドウは「ビルド」だけ見ない
ビルドが止まっているように見えて、実は NuGet や Git、デバッグの初期化が詰まっていることがあります。出力ウィンドウの表示先を切り替え、関連ログが出ていないか確認します。
| 出力の表示先 | 確認ポイント | 典型的な詰まり |
|---|---|---|
| ビルド | 最後に動いたプロジェクト/ターゲット/タスク | カスタムターゲットで外部ツール待ち、コピー処理でロック待ち |
| パッケージ マネージャー(NuGet) | restore の開始・失敗・リトライ、フィード到達性 | プロキシ/証明書/認証要求、キャッシュ破損 |
| ソース管理(Git) | 状態更新、サブモジュール、LFS、認証プロンプト | 資格情報待ち、巨大リポジトリのスキャン |
| デバッグ | デバッグエンジン初期化、シンボル読み込み | シンボルサーバ到達待ち、起動対象プロセスのハング |
ステータスバーからバックグラウンドタスクを確認する
見落とされがちですが、Visual Studio はバックグラウンド処理の状態をステータスバー付近に出すことがあります。環境や拡張の有無で見え方は変わりますが、次のような手がかりを探してください。
- ステータスバーの「準備完了(Ready)」表示や、その近くの小さなアイコン(進捗/同期/時計のような表示)をクリックすると、実行中タスクが表示される場合がある
- 「ソリューションの読み込み」「NuGet の復元」「テスト探索」「インデックス作成」など、ビルドとは別名の処理が残っていないか確認する
ここでタスク名が見えると、調査の方向性が一気に定まります。例えば「NuGet の復元」が残っているなら、ビルドのハングではなく restore の待ちです。逆にタスクが何も出ないのに止まる場合は、OS 側の待ち(ロック/権限/ネットワーク)を疑いやすくなります。
ActivityLog を採取して“内部エラーの足跡”を拾う
拡張機能やパッケージの読み込み失敗、内部例外が原因で処理が止まっているときは、ActivityLog が強い味方になります。ステータスバーが「Ready」でも、内部で例外が出続けて処理が進まないケースがあります。
ログの取り方
- Visual Studio を閉じる(可能なら)
- 次のコマンドでログを有効化して起動する
devenv.exe /log
- 問題を再現する(ビルド開始が止まるなど)
- Visual Studio を終了する
- 次の場所に生成される ActivityLog.xml を確認する
%AppData%\Microsoft\VisualStudio\17.0_<InstanceID>\ActivityLog.xml
%AppData%\Microsoft\VisualStudio\16.0_<InstanceID>\ActivityLog.xml
読み方のコツ
- 「Error」「Warning」「Exception」「LoadPackage」「Extension」などで検索する
- 同じエラーが繰り返し出ていないか(同一拡張の連発)を見る
- エラーの直前直後に「どのパッケージを読み込もうとしたか」「何に失敗したか」を拾う
ActivityLog は“原因の結論”が書かれないこともありますが、怪しい拡張機能の特定や、内部で何が読み込めていないかのヒントになります。
Windows 側から「何を待っているか」を突き止める
Visual Studio 側の表示やログに手掛かりが薄いときは、Windows の観測ツールで「devenv.exe が何を触りに行って、どこで待っているか」を見ます。社内環境や複数ツールが絡む現場ほど、OS レベルの待ちが真因になりがちです。
タスクマネージャーで“待ち”の種類を分類する
- CPU が高い:解析/コンパイル/インデックス作成などで本当に処理中。出力やタスク表示を掘る
- CPU が低いのに止まる:I/O待ち、ロック待ち、ネットワーク待ちの可能性が高い
- ディスクが張り付く:大量ファイルの列挙、ウイルス対策によるスキャン介入を疑う
環境によっては、devenv.exe を右クリックして「待機チェーンの分析(Analyze wait chain)」が使えます。ロックしている相手プロセスが見えるだけでも、打てる手が増えます。
Process Monitor(ProcMon)で devenv.exe の実アクセスを追う
ProcMon は、ファイル/レジストリ/ネットワークへのアクセスを時系列で追えるため、「どこで止まっているか」を強制的に可視化できます。ポイントはログを全部読むのではなく、絞って“異常な結果”だけ拾うことです。
最小構成のフィルター例
- Process Name is devenv.exe → Include
- 必要に応じて Process Name is msbuild.exe / dotnet.exe / VBCSCompiler.exe → Include
- Result is NAME NOT FOUND / ACCESS DENIED を優先的に追う
実務で多いのが「存在しないネットワークドライブ参照」です。たとえば昔の開発機で Z: を使っていて、今の環境では Z: が未割り当て。すると、PATH や SDK 参照に紛れた Z:\ が延々と探索され、結果としてビルドが始まらない/妙に待つことがあります。ProcMon で「NAME NOT FOUND が同じパスで連発」していないかを見ると、一発で当たりを引けます。
| ProcMonでよく見るサイン | 示唆する原因 | 次に確認すること |
|---|---|---|
| NAME NOT FOUND が同じパスで連発 | 存在しないディレクトリ/SDK/ツール参照、切れたネットワークドライブ | プロジェクト設定(パス)、環境変数(PATH 等)、参照先の実在、ドライブ割り当て |
| ACCESS DENIED | 権限不足、保護フォルダ、セキュリティ製品によるブロック | 書き込み先(obj/bin/.vs)権限、保護機能、除外設定の必要性 |
| CreateFile に時間がかかる/Network系が混ざる | UNCパス/共有フォルダ待ち、プロキシ、社内ネットワーク遅延 | プロジェクトがネットワーク上にないか、NuGet ソース、VPN、証明書 |
| 削除やリネームがリトライされる | ロック(別プロセスが掴んでいる) | ウイルス対策、エディタ、ビルド出力を開いているアプリ、同期ツール |
「Build started…」で止まるときに疑うポイント
出力が「Build started…」から動かないとき、実際には“ビルド開始前の準備”で止まっていることが多いです。現象の見え方と、優先して当たるべき場所をまとめます。
| 見え方 | 裏で起きがちなこと | 優先して見る場所 | よく効く対策 |
|---|---|---|---|
| 出力に「Build started…」だけ | Design-time build / restore / 拡張の初期化待ち | ステータスバーのタスク、パッケージマネージャー出力、ActivityLog | 冗長度を上げる、SafeModeで再現確認、NuGetソース見直し |
| 特定プロジェクト名で止まる | カスタムターゲット、コピー、署名、生成処理が外部待ち | ビルド出力(Diagnostic)、該当 .csproj / .targets | 外部ツールのパス・権限、ネットワーク参照の排除 |
| CPUは低いのに固まる | I/O待ち(ロック/ネットワーク/セキュリティ製品) | ProcMon、待機チェーン、ディスク使用率 | 除外設定、ロック解除、ローカル作業フォルダ化 |
| 初回だけ極端に遅い | キャッシュ再構築、インデックス、初回restore | タスク表示、ディスクI/O、出力 | .vs/objの作り直し、パッケージキャッシュ整備 |
よくある詰まり要因と、再現を止めるための現実的な対策
拡張機能が固まっている
拡張機能が原因だと、VS の表示上は正常でも、内部でパッケージ読み込みが止まってビルドやデバッグが連鎖的に進まないことがあります。まずは“拡張なし”で現象が消えるかを確認すると、調査時間を大きく短縮できます。
devenv.exe /safemode
- SafeMode で症状が消えるなら、拡張機能が第一容疑者
- 最近追加・更新した拡張を無効化し、段階的に戻して原因を特定する
- ActivityLog で同じ拡張名のエラーが連発していれば、優先度はさらに上がる
NuGet の復元が待ち状態
NuGet はネットワークや証明書の影響を受けやすく、特に社内環境(プロキシ、SSLインスペクション、認証付きフィード)では“止まったように見える待ち”が起きがちです。
- 出力ウィンドウを「パッケージ マネージャー」に切り替え、復元ログが進んでいるか確認する
- 複数のパッケージソースが登録されている場合、到達できないソースが混ざると全体が遅くなることがある
- キャッシュ破損が疑わしい場合は、ローカルキャッシュをクリアして挙動を変える
dotnet nuget locals all --clear
nuget locals all -clear
ネットワークパスや同期フォルダが混ざっている
プロジェクトがネットワーク共有(UNC)上にある、参照先に共有フォルダが混ざっている、OneDrive 等の同期対象フォルダで作業している――こうした条件は、I/O遅延やロックの温床です。特にビルド出力(bin/obj)や .vs が同期対象だと、生成と同期がぶつかって待ちが増えます。
- ソリューションと NuGet キャッシュ、ビルド出力(bin/obj/.vs)がローカルディスクにあるか
- プロジェクト参照のパスに UNC(\\server\share)や切断されたドライブ(例:Z:)が紛れていないか
- ProcMon でネットワークアクセスが連続していないか
セキュリティ製品(ウイルス対策)や保護機能の介入
ビルドは短時間に大量のファイルを生成・削除します。ウイルス対策や保護機能が介入すると、削除や生成が遅延/ブロックされ、結果としてビルド開始が待ちになることがあります。
- ProcMon で ACCESS DENIED が出ていないか
- ディスクI/Oが不自然に張り付いていないか
- 保護フォルダ配下に出力していないか(権限・保護ポリシーの影響を受けやすい)
対策としては、開発用フォルダをローカルの任意フォルダ(例:C:\dev)に寄せる、必要に応じて除外設定を検討する、などが現実的です(組織ポリシーに従って運用してください)。
ソリューションのキャッシュ破損(.vs / bin / obj など)
“昨日まで動いていたのに”という場合、キャッシュ破損が原因のことがあります。削除してもソースが消えるわけではなく、再生成されます。実施前に必ず Visual Studio を終了し、必要なら作業ブランチをコミットしておくと安全です。
- ソリューション直下の .vs フォルダを削除(非表示の場合あり)
- 各プロジェクトの bin / obj を削除
- 削除後に起動して、最初のビルドで再現が消えるか確認する
コマンドラインビルドで切り分ける(VS固有か、MSBuild/プロジェクト固有か)
“Visual Studio のビルドが止まる”のか、“MSBuild 自体が止まる”のかは、切り分ける価値が大きいです。Developer Command Prompt などから MSBuild を直接叩いて比較します。
msbuild YourSolution.sln /t:Build /m /v:diag
コマンドラインでは通るのに VS だけ止まるなら、拡張機能・設計時ビルド・ソリューション読み込み周りの可能性が上がります。逆にコマンドラインも止まるなら、プロジェクト設定や外部ツール待ち、ネットワーク参照など“プロジェクト側”の問題を疑うべきです。
MSBuild のバイナリログで「どのタスクで止まったか」を固定する
さらに一歩進めたい場合は、バイナリログ(binlog)を取ると強力です。Diagnostic 出力よりも構造化されており、タスクの呼び出し階層を追いやすくなります。
msbuild YourSolution.sln /t:Build /m /bl:msbuild.binlog /v:diag
ログが取れたら、どのプロジェクトのどのターゲットで時間が伸びているかを特定し、外部コマンドやファイルコピー、パッケージ復元などの“待ちポイント”に当たりを付けます。
「いま何をしているか」を言語化するチェックリスト
調査のゴールは、最終的に「VS が何をしている最中で止まっているか」を短い言葉で説明できる状態です。そこまで辿り着くためのチェックリストを用意します。
| 確認項目 | チェック方法 | 分かったら次にやること |
|---|---|---|
| 最後に出力されたターゲット/タスク名 | ビルド出力を Detailed/Diagnostic にして確認 | 該当ターゲットが外部コマンドやコピーを呼んでいないか確認 |
| バックグラウンドで残っているタスク名 | ステータスバー付近のタスク表示(クリック) | NuGet/テスト/インデックスなど“本体以外”の詰まりに分岐 |
| 例外や拡張のロード失敗 | ActivityLog.xml を検索 | 該当拡張を無効化、更新、または SafeMode で再現性を取る |
| OSレベルの待ち(パス不達/権限/ロック) | ProcMon で NAME NOT FOUND / ACCESS DENIED を追う | 参照パス修正、権限調整、除外設定、ローカル配置に変更 |
| VS固有か、MSBuild固有か | msbuild コマンドで同じターゲットを実行 | VS固有なら拡張/設計時ビルド、MSBuild固有ならプロジェクト設定へ |
どうしても解けないときの“最終手段”
大規模ソリューションや、社内制約が強い環境では、ここまでやっても原因がぼやけることがあります。その場合は「証拠」を採取して、確実に前へ進めます。
ハングダンプを採取してスレッド待ちを確認する
タスクマネージャーの「詳細」タブで devenv.exe を右クリックし、「ダンプファイルの作成」が可能なら取得します。解析できる担当者がいる場合、どのスレッドがどのロックを待っているかまで追えるため、原因の特定が一段深くなります。
Visual Studio Installer の修復や更新も選択肢に入れる
環境の破損(コンポーネント欠落、アップデート失敗)が疑われる場合は、Visual Studio Installer の「修復」も有効です。ただし、ActivityLog や ProcMon の結果を先に確保しておくと、再発時にも迷いません。
まとめ:止まっている“場所”が分かれば、解決策は具体化する
「Ready なのにビルドできない」「Build started…で止まる」は、原因の多くがバックグラウンドタスクの待ちかOSレベルの待ちにあります。出力の詳細化→ステータスバーのタスク確認→ActivityLog→ProcMon の順で情報を積み上げれば、「いま何をしているか」を言語化でき、拡張の無効化、NuGet の復元対策、パス修正、ロック解除など、次の具体策に直結します。

コメント