setup-local-sdk
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesesetup-local-sdk
本地SDK安装指南
Purpose
目的
Guide the user through installing a .NET SDK into a project-local
directory and wiring it up via the feature (.NET 10+).
The examples use .NET 11, but this works with any version — prerelease or stable.
.dotnet/global.jsonpathsThe result is a fully isolated SDK that:
- Does not modify the system-wide .NET installation.
- Is picked up automatically by commands from the project root.
dotnet - Can be deleted to revert (or
rm -rf .dotnet/).Remove-Item -Recurse -Force .\.dotnet
指导用户将.NET SDK安装到项目本地的目录,并通过的功能(.NET 10及以上版本)进行配置。示例中使用的是.NET 11,但该方法适用于所有版本——预发布版或稳定版均可。
.dotnet/global.jsonpaths最终得到的是一个完全隔离的SDK,具备以下特性:
- 不会修改系统级的.NET安装。
- 位于项目根目录时,会被命令自动识别。
dotnet - 可通过删除目录恢复(执行或
rm -rf .dotnet/)。Remove-Item -Recurse -Force .\\.dotnet
When NOT to use
不适用场景
- User wants a system-wide install — direct to the official installer.
- Host is older than v10 —
dotnetdoesn't exist; explain and stop.paths - User needs a runtime-only install — applies to SDK resolution only.
paths
- 用户需要系统级安装——直接使用官方安装程序。
- 宿主版本低于v10——
dotnet功能不存在;需告知用户并终止操作。paths - 用户仅需仅运行时安装——仅适用于SDK解析。
paths
Inputs / Prerequisites
输入项 / 前置条件
| Input | Required | Default | Notes |
|---|---|---|---|
| Channel or version | No | | e.g. |
| Quality | No | | One of: |
| jq | No | — | Optional for bash team scripts when patching an existing |
| 输入项 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
| 通道或版本 | 否 | | 例如 |
| 版本质量 | 否 | | 可选值: |
| jq | 否 | — | 在bash团队脚本中修补现有 |
Prerequisites
前置条件
- A .NET 10+ SDK is installed globally — run ; major ≥ 10.
dotnet --version - curl (macOS/Linux) or PowerShell (Windows) is available.
- 已全局安装.NET 10及以上版本的SDK——运行检查;主版本号≥10。
dotnet --version - 已安装curl(macOS/Linux)或PowerShell(Windows)。
Workflow
操作流程
Step 1 — Clarify what to install
步骤1 — 明确安装需求
If the user didn't specify, ask what .NET SDK version they want (e.g., "latest
.NET 11 preview" or an exact version like ).
Map the answer to / or flags.
11.0.100-preview.2.26159.112--channel--quality--version若用户未指定,询问其想要安装的.NET SDK版本(例如“最新.NET 11预览版”或精确版本)。将用户的回答映射为/或参数。
11.0.100-preview.2.26159.112--channel--quality--versionStep 2 — Verify .NET 10+ host
步骤2 — 验证.NET 10+宿主版本
If the user already provided output, treat that as the
authoritative version for their machine. Do not override it with the agent
workspace's version; if the two differ, explain that the workspace differs and
continue advising for the user's machine.
dotnet --versionbash
dotnet --versionIf major version < 10, stop before downloading anything: the feature
requires a .NET 10+ host SDK. Tell the user to install .NET 10 or later
system-wide first, then return to the local SDK setup.
paths若用户已提供的输出结果,则以此作为其机器上的权威版本。请勿使用Agent工作区的版本覆盖该值;若两者不同,需说明工作区版本与用户机器版本存在差异,并继续针对用户机器提供指导。
dotnet --versionbash
dotnet --version若主版本号<10,在下载任何内容前终止操作:功能需要.NET 10及以上版本的宿主SDK。告知用户先全局安装.NET 10或更高版本,再返回本地SDK安装流程。
pathsStep 3 — Detect operating system
步骤3 — 检测操作系统
Run . If it succeeds (including , , —
these are bash-capable environments like Git Bash) → use bash/.
If it fails (native Windows without Git Bash) → use PowerShell/.
uname -s 2>/dev/nullMINGW*MSYS*CYGWIN*dotnet-install.shdotnet-install.ps1运行。若命令执行成功(包括、、——这些是支持bash的环境,如Git Bash)→ 使用bash/脚本。若命令执行失败(原生Windows且未安装Git Bash)→ 使用PowerShell/脚本。
uname -s 2>/dev/nullMINGW*MSYS*CYGWIN*dotnet-install.shdotnet-install.ps1Step 4 — Check for existing local SDK
步骤4 — 检查现有本地SDK
macOS / Linux:
bash
test -d .dotnet && echo "exists" || echo "not found"Windows (PowerShell):
powershell
if (Test-Path -LiteralPath .\.dotnet) { "exists" } else { "not found" }If exists, ask: update with the new version, or skip and keep it?
.dotnet/macOS / Linux:
bash
test -d .dotnet && echo "exists" || echo "not found"Windows(PowerShell):
powershell
if (Test-Path -LiteralPath .\\.dotnet) { "exists" } else { "not found" }若目录已存在,询问用户:是使用新版本更新,还是保留现有版本跳过安装?
.dotnet/Step 5 — Download and run the install script
步骤5 — 下载并运行安装脚本
macOS / Linux:
bash
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 .dotnetWindows (PowerShell):
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
}
}For exact versions: use (bash) or (PowerShell)
instead of channel/quality flags. The install scripts are from Microsoft's official
URLs: and .
--version <VERSION>-Version <VERSION>https://dot.net/v1/dotnet-install.shhttps://dot.net/v1/dotnet-install.ps1macOS / Linux:
bash
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 .dotnetWindows(PowerShell):
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
}
}若安装精确版本:使用(bash)或(PowerShell)参数替代通道/版本质量参数。安装脚本来自微软官方地址:和。
--version <VERSION>-Version <VERSION>https://dot.net/v1/dotnet-install.shhttps://dot.net/v1/dotnet-install.ps1Step 6 — Identify the installed version
步骤6 — 确认已安装版本
bash
./.dotnet/dotnet --version # macOS/Linux
.\.dotnet\dotnet.exe --version # WindowsRecord the exact version string (e.g., ) for .
11.0.100-preview.2.26159.112global.jsonbash
./.dotnet/dotnet --version # macOS/Linux
.\\.dotnet\\dotnet.exe --version # Windows记录精确版本字符串(例如),用于配置。
11.0.100-preview.2.26159.112global.jsonStep 7 — Create or update global.json
步骤7 — 创建或更新global.json
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."
}
}- :
pathsfirst (local priority),.dotnet= system-wide fallback.$host$ - : use for latest-preview or floating feature-band installs.
rollForward: "latestFeature" - Exact version requests: use so SDK resolution doesn't move to a different feature band.
rollForward: "disable" - : set to
allowPrereleaseonly when installing a prerelease SDK. Omit for stable versions.true - : include only when team install scripts are created (Step 10). Otherwise omit.
errorMessage
If already exists, merge carefully: preserve existing properties (,
, etc.) and only add/update the section. Read the existing file first, update/add
the object, then write it back. This ensures cross-project config (e.g., MSBuild settings)
isn't lost. Always back up the original file (e.g., ) before modifying.
global.jsonmsbuild-sdkstoolssdksdkglobal.json.bakMinimal config (when version pinning isn't needed):
{"sdk":{"paths":[".dotnet","$host$"]}}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表示系统级安装作为 fallback。$host$ - :用于安装最新预览版或浮动功能带版本时。
rollForward: "latestFeature" - 若要求精确版本:使用,确保SDK解析不会切换到其他功能带。
rollForward: "disable" - :仅在安装预发布版SDK时设置为
allowPrerelease。稳定版可省略该配置。true - :仅在创建团队安装脚本(步骤10)时添加。否则请省略。
errorMessage
若已存在,需谨慎合并:保留现有属性(如、等),仅添加或更新部分。需先读取现有文件,更新或添加对象,再写回文件。这样可确保跨项目配置(如MSBuild设置)不会丢失。修改前请务必备份原始文件(例如)。
global.jsonmsbuild-sdkstoolssdksdkglobal.json.bak极简配置(无需固定版本时):
{"sdk":{"paths":[".dotnet","$host$"]}}Step 8 — Update .gitignore
步骤8 — 更新.gitignore
macOS / Linux (or Git Bash):
bash
grep -qxF '.dotnet/' .gitignore 2>/dev/null || printf '\n.dotnet/\n' >> .gitignoreWindows (PowerShell):
powershell
if (-not (Test-Path .gitignore) -or -not (Select-String -Path .gitignore -Pattern '^\.dotnet/$' -Quiet)) {
Add-Content -Path .gitignore -Value '.dotnet/'
}macOS / Linux(或Git Bash):
bash
grep -qxF '.dotnet/' .gitignore 2>/dev/null || printf '\
.dotnet/\
' >> .gitignoreWindows(PowerShell):
powershell
if (-not (Test-Path .gitignore) -or -not (Select-String -Path .gitignore -Pattern '^\\.dotnet/$' -Quiet)) {
Add-Content -Path .gitignore -Value '.dotnet/'
}Step 9 — Install workloads (if requested)
步骤9 — 安装工作负载(如有需求)
Only do this after and are complete, so a slow or
platform-limited workload install does not prevent the base local SDK setup from
being usable.
global.json.gitignoreIf the user mentioned MAUI, mobile, workload, Blazor WASM, or cross-platform,
install using the local binary (no sudo needed):
bash
./.dotnet/dotnet workload install <workload> # macOS/Linux
.\.dotnet\dotnet.exe workload install <workload> # WindowsVerify: (or ).
./.dotnet/dotnet workload list.\.dotnet\dotnet.exe workload listFor MAUI, pick a workload supported by the current OS and target platform. On
Linux, the full meta-workload is not available; use a supported workload
such as when Android is the target, or explain the platform
limitation and ask which target to configure.
mauimaui-androidAlways use the local dotnet binary for workload commands. Workload metadata is stored relative to the host process's dotnet root. The systemputs metadata in the wrong location. (See dotnet/sdk#49825.)dotnet
仅在和配置完成后执行此步骤,避免缓慢或受平台限制的工作负载安装影响基础本地SDK的可用性。
global.json.gitignore若用户提到MAUI、移动开发、工作负载、Blazor WASM或跨平台开发,使用本地二进制文件进行安装(无需sudo权限):
bash
./.dotnet/dotnet workload install <workload> # macOS/Linux
.\\.dotnet\\dotnet.exe workload install <workload> # Windows验证安装:执行(或)。
./.dotnet/dotnet workload list.\.dotnet\dotnet.exe workload list对于MAUI,请选择当前操作系统和目标平台支持的工作负载。在Linux上,完整的元工作负载不可用;请使用支持的工作负载,例如当目标平台为Android时使用,或说明平台限制并询问用户需要配置哪个目标平台。
mauimaui-android始终使用本地dotnet二进制文件执行工作负载命令。 工作负载元数据存储在宿主进程的dotnet根目录相对路径下。系统级会将元数据存储在错误位置。(详情见dotnet/sdk#49825。)dotnet
Step 10 — Create team install scripts
步骤10 — 创建团队安装脚本
Create if user mentioned "team", "share", "CI", "scripts", etc. Otherwise offer.
These examples back up and preserve existing settings. The bash script
uses when an existing must be patched; if is unavailable,
it refuses to overwrite the file and prints the settings to merge manually.
Adapt script variables to the install choice from Step 1: exact versions should
use / and ; channel installs should
use channel/quality and only set for prerelease SDKs.
If already pins and the user mainly needs team
scripts, reuse that version in the scripts and update first; do
not start a long SDK download just to discover the version. When the user asks
for both setup and scripts, create the scripts/config before any long install so
the reproducible setup exists even if download or workload installation is slow.
global.jsonjqglobal.jsonjq--version-VersionrollForward: "disable"allowPrerelease: trueglobal.jsonsdk.versionglobal.jsoninstall-dotnet.sh:
bash
#!/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"bash
chmod +x install-dotnet.shinstall-dotnet.ps1:
powershell
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"Commit these scripts to the repo so teammates can run them.
若用户提到“团队”、“共享”、“CI”、“脚本”等关键词,则创建脚本。否则可主动提供。以下示例会备份并保留现有设置。bash脚本在需要修补现有时使用;若未安装jq,脚本会拒绝覆盖文件,并打印需手动合并的配置。根据步骤1的安装选择调整脚本变量:精确版本应使用/参数和;通道安装应使用通道/版本质量参数,且仅在安装预发布版SDK时设置。若已固定且用户主要需要团队脚本,请在脚本中复用该版本并先更新;不要为了获取版本而启动长时间的SDK下载。当用户同时要求安装和脚本时,请在进行长时间安装前创建脚本/配置,确保即使下载或工作负载安装缓慢,可复现的安装环境依然存在。
global.jsonglobal.jsonjq--version-VersionrollForward: "disable"allowPrerelease: trueglobal.jsonsdk.versionglobal.jsoninstall-dotnet.sh:
bash
#!/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 '\
.dotnet/\
' >> .gitignore
[ ${#WORKLOADS[@]} -gt 0 ] && "$INSTALL_DIR/dotnet" workload install "${WORKLOADS[@]}"
echo "Done. SDK: $SDK_VERSION"bash
chmod +x install-dotnet.shinstall-dotnet.ps1:
powershell
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"将这些脚本提交到代码仓库,以便团队成员运行。
Step 11 — Verify SDK resolution
步骤11 — 验证SDK解析
bash
dotnet --versionOutput should match the locally installed version. If not, check: global.json
location, array contents, host dotnet version ≥ 10.
pathsbash
dotnet --version输出应与本地安装的版本一致。若不一致,请检查:global.json的位置、数组内容、宿主dotnet版本是否≥10。
pathsStep 12 — Summarize and explain cleanup
步骤12 — 总结并说明清理方法
Tell the user: SDK installed, global.json configured, .dotnet/ gitignored, system
install untouched. Cleanup: delete , remove / from
global.json, optionally delete install scripts. Include the final
values (or a short snippet) so the user can see the configured version,
, and any . If workloads were requested, include the local
command used and the workload verification result
or the exact blocker if the workload could not be installed.
.dotnet/pathserrorMessageglobal.jsonsdkpathserrorMessagedotnet workload install ...告知用户:SDK已安装、global.json已配置、.dotnet/已加入git忽略、系统级安装未受影响。清理方法:删除目录,从global.json中移除/配置,可选择删除安装脚本。附上最终的global.json的配置值(或简短代码片段),以便用户查看已配置的版本、及任何。若用户要求安装工作负载,需附上使用的本地命令及工作负载验证结果,若安装失败则说明具体障碍。
.dotnet/pathserrorMessagesdkpathserrorMessagedotnet workload install ...Common pitfalls
常见问题
| Pitfall | Cause | Fix |
|---|---|---|
| Host | Install .NET 10+ system-wide |
| Wrong SDK resolves | | Check for global.json up the tree |
| Teammates get "SDK not found" | | Use |
| Workloads missing | Used system | Use |
| | Use |
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 宿主 | 全局安装.NET 10及以上版本 |
| 解析到错误的SDK | 父目录存在global.json | 检查上级目录是否有global.json |
| 团队成员提示“SDK未找到” | | 在global.json中添加 |
| 工作负载缺失 | 使用了系统级 | 使用 |
| | 使用 |