mcpField
S
setup-local-sdk

setup-local-sdk

github.com/dotnet開発5.8k3.1k 回インストール1 日前に更新
リポジトリ

setup-local-sdk について

プロジェクト内の `.dotnet/` に .NET SDK をインストールし、`global.json` で選択する手順を案内するスキルです。システム全体の SDK に変更を加えず、設定の確認や削除方法も扱います。

主な機能

  1. 01プロジェクト内への SDK インストール
  2. 02`global.json` の paths 設定
  3. 03ホストバージョン要件の確認
  4. 04OS 別のインストール手順
  5. 05必要に応じた workload のインストール
  6. 06チーム向けセットアップスクリプト

活用シーン

  1. 01プロジェクト単位での SDK 分離
  2. 02プレビュー版や指定バージョンの SDK 設定
  3. 03チームや CI 用の再現可能な設定準備
  4. 04ローカル SDK の削除による設定の取り消し

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dotnet/skills --skill setup-local-sdk

インストール後、Claude Code で/setup-local-sdkを入力して読み込まれたか確認します。

詳細

setup-local-sdk

目的

.NET SDK をプロジェクトローカルの .dotnet/ ディレクトリにインストールし、global.json の paths 機能(.NET 10 以降)で設定する手順を説明します。 例では .NET 11 を使用していますが、プレビュー版でも安定版でも、どのバージョンでも動作します。

この方法では、完全に分離された SDK を利用できます。

  • システム全体の .NET インストールは変更されません。
  • プロジェクトのルートから dotnet コマンドを実行すると、自動的に使用されます。
  • 削除すれば元に戻せます(rm -rf .dotnet/ または Remove-Item -Recurse -Force .\.dotnet)。

使用しない場合

  • ユーザーがシステム全体へのインストールを希望している場合は、公式インストーラーを案内してください。
  • ホストの dotnet が v10 より古い場合は、paths が存在しないことを説明して終了してください。
  • ユーザーがランタイムのみのインストールを必要としている場合は、paths は SDK の解決にのみ適用されます。

入力/前提条件

入力必須デフォルト備考
チャネルまたはバージョンいいえ11.0例:11.0、STS、LTS、または 11.0.100-preview.2.26159.112 のような正確なバージョン
品質いいえpreviewdaily、preview、ga のいずれか
jqいいえ—既存の global.json を修正する bash チームスクリプトで任意使用します。使用できない場合は、ファイルを上書きしないでください
前提条件
  1. .NET 10 以降の SDK がグローバルにインストールされていること — dotnet --version を実行し、メジャーバージョンが 10 以上であることを確認します。
  2. curl(macOS/Linux)または PowerShell(Windows)が使用できること。

ワークフロー

ステップ 1 — インストールする SDK を確認する

ユーザーが指定していない場合は、希望する .NET SDK のバージョンを尋ねます(例:「最新の .NET 11 プレビュー版」または 11.0.100-preview.2.26159.112 のような正確なバージョン)。 回答に応じて、--channel/--quality フラグまたは --version フラグを指定します。

ステップ 2 — .NET 10 以降のホストを確認する

ユーザーがすでに dotnet --version の出力を提示している場合は、そのバージョンをユーザーのマシンの 正確なバージョンとして扱います。エージェントのワークスペースのバージョンで上書きしないでください。2 つのバージョンが異なる場合は、ワークスペースのバージョンが異なることを説明したうえで、 ユーザーのマシン向けの案内を続けます。

dotnet --version

メジャーバージョンが 10 未満の場合は、何もダウンロードせずに終了します。paths 機能には .NET 10 以降のホスト SDK が必要です。まず .NET 10 以降をシステム全体にインストールしてから、ローカル SDK のセットアップに戻るようユーザーに伝えてください。

ステップ 3 — オペレーティングシステムを検出する

uname -s 2>/dev/null を実行します。成功した場合(MINGW*、MSYS*、CYGWIN* を含む。これらは Git Bash などの bash を使用できる環境です)は、bash/dotnet-install.sh を使用します。 失敗した場合(Git Bash を使っていないネイティブ Windows)は、PowerShell/dotnet-install.ps1 を使用します。

ステップ 4 — 既存のローカル SDK を確認する

macOS/Linux:

test -d .dotnet && echo "exists" || echo "not found"

Windows(PowerShell):

if (Test-Path -LiteralPath .\.dotnet) { "exists" } else { "not found" }

.dotnet/ が存在する場合は、新しいバージョンに更新するか、そのまま残してスキップするかを尋ねます。

ステップ 5 — インストールスクリプトをダウンロードして実行する

macOS/Linux:

INSTALL_SCRIPT="$(mktemp "${TMPDIR:-/tmp}/dotnet-install.XXXXXX")"
trap 'rm -f "$INSTALL_SCRIPT"' EXIT
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$INSTALL_SCRIPT"
bash "$INSTALL_SCRIPT" --channel <CHANNEL> --quality <QUALITY> --install-dir .dotnet

Windows(PowerShell):

$installScript = Join-Path $env:TEMP "dotnet-install-$([guid]::NewGuid()).ps1"
try {
    Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile $installScript
    & $installScript -Channel <CHANNEL> -Quality <QUALITY> -InstallDir .dotnet
}
finally {
    if (Test-Path -LiteralPath $installScript) {
        Remove-Item -LiteralPath $installScript -Force
    }
}

正確なバージョンを指定する場合は、チャネル/品質フラグの代わりに --version <VERSION>(bash)または -Version <VERSION>(PowerShell)を使用します。インストールスクリプトの配布元は、Microsoft の公式 URL である https://dot.net/v1/dotnet-install.sh と https://dot.net/v1/dotnet-install.ps1 です。

ステップ 6 — インストールしたバージョンを特定する
./.dotnet/dotnet --version          # macOS/Linux
.\.dotnet\dotnet.exe --version      # Windows

global.json に指定するため、正確なバージョン文字列(例:11.0.100-preview.2.26159.112)を記録します。

ステップ 7 — global.json を作成または更新する
{
  "sdk": {
    "version": "<INSTALLED_VERSION>",
    "allowPrerelease": true,
    "rollForward": "latestFeature",
    "paths": [".dotnet", "$host$"],
    "errorMessage": "Required .NET SDK not found. Run ./install-dotnet.sh (or .ps1) to install it locally."
  }
}
  • paths:.dotnet を先に指定します(ローカルを優先)。$host$ はシステム全体へのフォールバックです。
  • rollForward: "latestFeature":最新プレビュー版またはフィーチャーバンドを固定しないインストールで使用します。
  • バージョンを正確に指定する場合:SDK の解決で別のフィーチャーバンドに移動しないよう、rollForward: "disable" を使用します。
  • allowPrerelease:プレリリース SDK をインストールする場合にのみ true に設定します。安定版では省略します。
  • errorMessage:チーム用のインストールスクリプトを作成する場合(ステップ 10)にのみ含めます。それ以外では省略します。

global.json がすでに存在する場合は、慎重にマージします。既存のプロパティ(msbuild-sdks、tools など)を保持し、sdk セクションのみを追加または更新します。既存のファイルを先に読み込み、sdk オブジェクトを更新または追加してから、書き戻します。これにより、プロジェクト間で共有する設定(MSBuild 設定など)が失われないようにできます。変更する前に、必ず元のファイルをバックアップしてください(例:global.json.bak)。

最小構成(バージョンの固定が不要な場合): {"sdk":{"paths":[".dotnet","$host$"]}}

ステップ 8 — .gitignore を更新する

macOS / Linux(または Git Bash):

grep -qxF '.dotnet/' .gitignore 2>/dev/null || printf '\n.dotnet/\n' >> .gitignore

Windows(PowerShell):

if (-not (Test-Path .gitignore) -or -not (Select-String -Path .gitignore -Pattern '^\.dotnet/$' -Quiet)) {
    Add-Content -Path .gitignore -Value '.dotnet/'
}
ステップ 9 — ワークロードをインストールする(要望がある場合)

global.json と .gitignore の設定が完了してから実行してください。時間のかかるワークロードのインストールやプラットフォーム上の制約によって、基本的なローカル SDK のセットアップが使用できなくなるのを防げます。

ユーザーが MAUI、モバイル、ワークロード、Blazor WASM、またはクロスプラットフォームに言及した場合は、ローカルバイナリを使用してインストールします(sudo は不要です)。

./.dotnet/dotnet workload install <workload>       # macOS/Linux
.\.dotnet\dotnet.exe workload install <workload>   # Windows

確認します:./.dotnet/dotnet workload list(または .\.dotnet\dotnet.exe workload list)。

MAUI では、現在の OS とターゲットプラットフォームでサポートされているワークロードを選択します。Linux では、完全な maui メタワークロードは利用できません。Android がターゲットの場合は maui-android などのサポート対象ワークロードを使用するか、プラットフォーム上の制約を説明し、設定するターゲットを確認してください。

ワークロードコマンドには、必ずローカルの dotnet バイナリを使用してください。 ワークロードのメタデータは、ホストプロセスの dotnet ルートを基準に保存されます。システムの dotnet を使用すると、メタデータが誤った場所に保存されます(dotnet/sdk#49825 を参照)。

ステップ 10 — チーム用のインストールスクリプトを作成する

ユーザーが「team」「share」「CI」「scripts」などに言及した場合は作成します。それ以外の場合は、作成を提案します。以下の例では global.json をバックアップし、既存の設定を保持します。既存の global.json を修正する必要がある場合、bash スクリプトは jq を使用します。jq がない場合は、ファイルの上書きを拒否し、手動でマージする設定を表示します。ステップ 1 で選択したインストール方法に合わせて、スクリプトの変数を調整してください。バージョンを正確に指定する場合は --version / -Version と rollForward: "disable" を使用します。チャネル指定のインストールでは、チャネルと品質を指定し、プレリリース SDK の場合にのみ allowPrerelease: true を設定します。global.json ですでに sdk.version が固定されており、ユーザーが主にチーム用スクリプトを必要としている場合は、そのバージョンをスクリプトで再利用し、先に global.json を更新します。バージョンを確認するためだけに、時間のかかる SDK のダウンロードを開始しないでください。ユーザーがセットアップとスクリプトの両方を求めている場合は、ダウンロードやワークロードのインストールに時間がかかっても再現可能なセットアップを用意できるよう、時間のかかるインストールを始める前にスクリプトと設定を作成します。

install-dotnet.sh:

#!/usr/bin/env bash
set -euo pipefail
INSTALL_DIR=".dotnet"
CHANNEL="11.0"
QUALITY="preview"
VERSION=""
ROLL_FORWARD="latestFeature"
ALLOW_PRERELEASE="true"
WORKLOADS=("${@}")
ERROR_MESSAGE="Required .NET SDK not found. Run ./install-dotnet.sh (or .ps1) to install it locally."
INSTALL_SCRIPT="$(mktemp "${TMPDIR:-/tmp}/dotnet-install.XXXXXX")"
GLOBAL_JSON_TMP=""
cleanup() {
    rm -f "$INSTALL_SCRIPT"
    [ -n "$GLOBAL_JSON_TMP" ] && rm -f "$GLOBAL_JSON_TMP"
}
trap cleanup EXIT
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$INSTALL_SCRIPT"
INSTALL_ARGS=(--install-dir "$INSTALL_DIR")
if [ -n "$VERSION" ]; then
    INSTALL_ARGS+=(--version "$VERSION")
    ROLL_FORWARD="disable"
else
    INSTALL_ARGS+=(--channel "$CHANNEL" --quality "$QUALITY")
fi
bash "$INSTALL_SCRIPT" "${INSTALL_ARGS[@]}"
SDK_VERSION=$("$INSTALL_DIR/dotnet" --version)
write_global_json() {
    if [ -f global.json ]; then
        cp global.json global.json.bak
        if ! command -v jq >/dev/null 2>&1; then
            echo "global.json exists; install succeeded, but this script will not overwrite it without jq." >&2
            echo "Merge these sdk settings manually so existing global.json properties are preserved:" >&2
            cat >&2 <<EOF
{
  "sdk": {
    "version": "$SDK_VERSION",
    "allowPrerelease": $ALLOW_PRERELEASE,
    "rollForward": "$ROLL_FORWARD",
    "paths": [".dotnet", "\$host\$"],
    "errorMessage": "$ERROR_MESSAGE"
  }
}
EOF
            exit 1
        fi
        GLOBAL_JSON_TMP="$(mktemp "${TMPDIR:-/tmp}/global-json.XXXXXX")"
        jq --arg version "$SDK_VERSION" --arg rollForward "$ROLL_FORWARD" --argjson allowPrerelease "$ALLOW_PRERELEASE" --arg errorMessage "$ERROR_MESSAGE" '
          .sdk = ((.sdk // {}) + {
            version: $version,
            allowPrerelease: $allowPrerelease,
            rollForward: $rollForward,
            paths: [".dotnet", "$host$"],
            errorMessage: $errorMessage
          })
        ' global.json > "$GLOBAL_JSON_TMP"
        mv "$GLOBAL_JSON_TMP" global.json
        GLOBAL_JSON_TMP=""
    else
        cat > global.json <<EOF
{
  "sdk": {
    "version": "$SDK_VERSION",
    "allowPrerelease": $ALLOW_PRERELEASE,
    "rollForward": "$ROLL_FORWARD",
    "paths": [".dotnet", "\$host\$"],
    "errorMessage": "$ERROR_MESSAGE"
  }
}
EOF
    fi
}
write_global_json
grep -qxF '.dotnet/' .gitignore 2>/dev/null || printf '\n.dotnet/\n' >> .gitignore
[ ${#WORKLOADS[@]} -gt 0 ] && "$INSTALL_DIR/dotnet" workload install "${WORKLOADS[@]}"
echo "Done. SDK: $SDK_VERSION"
chmod +x install-dotnet.sh

install-dotnet.ps1:

param([string[]]$Workloads = @())
$ErrorActionPreference = 'Stop'
$installDir = '.dotnet'; $channel = '11.0'; $quality = 'preview'
$version = ''; $rollForward = 'latestFeature'; $allowPrerelease = $true
$errorMessage = 'Required .NET SDK not found. Run ./install-dotnet.sh (or .ps1) to install it locally.'
$installScript = Join-Path $env:TEMP "dotnet-install-$([guid]::NewGuid()).ps1"
try {
    Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile $installScript
    $installArgs = @('-InstallDir', $installDir)
    if ($version) {
        $installArgs += @('-Version', $version)
        $rollForward = 'disable'
    } else {
        $installArgs += @('-Channel', $channel, '-Quality', $quality)
    }
    & $installScript @installArgs
}
finally {
    if (Test-Path -LiteralPath $installScript) {
        Remove-Item -LiteralPath $installScript -Force
    }
}
$sdkVersion = & "$installDir\dotnet.exe" --version
$globalJson = if (Test-Path 'global.json') {
    Copy-Item 'global.json' 'global.json.bak'
    Get-Content -Path 'global.json' -Raw | ConvertFrom-Json
} else {
    [pscustomobject]@{}
}
if (-not $globalJson.PSObject.Properties['sdk']) {
    $globalJson | Add-Member -MemberType NoteProperty -Name 'sdk' -Value ([pscustomobject]@{})
}
$updates = [ordered]@{
    version = $sdkVersion
    allowPrerelease = $allowPrerelease
    rollForward = $rollForward
    paths = @('.dotnet', '$host$')
    errorMessage = $errorMessage
}
foreach ($entry in $updates.GetEnumerator()) {
    $property = $globalJson.sdk.PSObject.Properties[$entry.Key]
    if ($property) {
        $property.Value = $entry.Value
    } else {
        $globalJson.sdk | Add-Member -MemberType NoteProperty -Name $entry.Key -Value $entry.Value
    }
}
$globalJson | ConvertTo-Json -Depth 10 | Set-Content -Path 'global.json' -Encoding UTF8
if (-not (Test-Path .gitignore) -or -not (Select-String -Path .gitignore -Pattern '^\.dotnet/$' -Quiet)) {
    Add-Content -Path .gitignore -Value '.dotnet/'
}
if ($Workloads.Count -gt 0) { & "$installDir\dotnet.exe" workload install @Workloads }
Write-Host "Done. SDK: $sdkVersion"

チームメンバーが実行できるよう、これらのスクリプトをリポジトリにコミットします。

ステップ 11 — SDK の解決を確認する
dotnet --version

出力がローカルにインストールされたバージョンと一致するはずです。一致しない場合は、global.json の場所、paths 配列の内容、ホストの dotnet バージョンが 10 以上であることを確認してください。

ステップ 12 — クリーンアップを要約して説明する

ユーザーに、SDK をインストールしたこと、global.json を設定したこと、.dotnet/ を gitignore に追加したこと、システムのインストールには変更を加えていないことを伝えます。クリーンアップでは、.dotnet/ を削除し、global.json から paths/errorMessage を削除し、必要に応じてインストールスクリプトも削除します。設定されたバージョン、paths、および errorMessage があれば確認できるよう、最終的な global.json の sdk 値(または短いスニペット)を記載します。ワークロードがリクエストされていた場合は、使用したローカルの dotnet workload install ... コマンドと、ワークロードの検証結果、またはインストールできなかった場合は正確な阻害要因を記載します。

よくある落とし穴

落とし穴原因対処方法
paths が無視されるホストの dotnet が v10 未満.NET 10 以降をシステム全体にインストールする
誤った SDK が解決される親ディレクトリに global.json があるディレクトリツリーをさかのぼって global.json を確認する
チームメイトに「SDK が見つからない」と表示される.dotnet/ が gitignore されていて、インストールスクリプトが実行されていないglobal.json で errorMessage を使う
ワークロードが見つからないローカルの dotnet ではなくシステムの dotnet を使用した./.dotnet/dotnet workload install を使う
dotnet app.dll で誤ったランタイムが使われるpaths は SDK 専用であり、apphost 用ではないdotnet run を使うか、DOTNET_ROOT を設定する

コメント