windows中安装Claude Code保姆教程

6 mins to read

手动下载 + 离线安装

步骤 1:启用 WSL 和虚拟机平台功能(无需联网)

以管理员身份打开 PowerShell,执行:

# 启用 WSL 功能
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

# 启用虚拟机平台(WSL2 必需)
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

⚠️ 执行后必须重启计算机。

步骤 2:手动下载并安装 WSL2 内核更新包

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

步骤 3:设置 WSL2 为默认版本

重启后,打开 PowerShell(普通用户权限):

wsl --set-default-version 2

步骤 4:手动安装 Linux 发行版到 D 盘(避免 C 盘占用)

从ubuntu官网下载,清华源已失效:https://cloud-images.ubuntu.com/wsl/releases/24.04/20240423/ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz

wsl --import Ubuntu D:\wsl-distros\Ubuntu D:\ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz --version 2

首次启动并创建用户:

adduser yourname
usermod -aG sudo yourname
echo -e "[user]\ndefault = yourname" > /etc/wsl.conf

退出后执行:

wsl --terminate Ubuntu
wsl -d Ubuntu

步骤5: 替换源

sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null << 'EOF'
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
# Types: deb-src
# URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
# Suites: noble noble-updates noble-backports
# Components: main restricted universe multiverse
# Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

# Types: deb-src
# URIs: http://security.ubuntu.com/ubuntu/
# Suites: noble-security
# Components: main restricted universe multiverse
# Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

# 预发布软件源,不建议启用

# Types: deb
# URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
# Suites: noble-proposed
# Components: main restricted universe multiverse
# Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

# # Types: deb-src
# # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
# # Suites: noble-proposed
# # Components: main restricted universe multiverse
# # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF

可选:一键设置代理

#!/bin/bash
# WSL2 代理管理脚本 - 带详细调试日志
# 用法: source ~/bin/proxy-debug.sh && proxy-on

set -euo pipefail  # 严格模式:出错立即退出

# ==================== 调试日志函数 ====================
LOG_LEVEL=${LOG_LEVEL:-2}  # 0=静默, 1=错误, 2=常规, 3=详细

log() {
    local level=$1; shift
    local msg="$*"
    local prefix=""
    
    case $level in
        1) prefix="❌ ERROR" ;;
        2) prefix="ℹ️  INFO" ;;
        3) prefix="🔍 DEBUG" ;;
        *) prefix="💬 LOG" ;;
    esac
    
    if [ $level -le $LOG_LEVEL ]; then
        echo "[$(date +'%H:%M:%S')] $prefix: $msg" >&2
    fi
}

# ==================== 核心函数(带超时保护) ====================

get_windows_host_ip() {
    log 2 "→ 步骤1: 获取 Windows 主机 IP"
    
    # 检查 /etc/resolv.conf 是否可读
    if ! timeout 2 test -r /etc/resolv.conf 2>/dev/null; then
        log 1 "/etc/resolv.conf 不可读或锁定,尝试修复..."
        sudo chattr -i /etc/resolv.conf 2>/dev/null || true
        sleep 0.5
    fi
    
    # 方法1: 从 resolv.conf 读取
    log 3 "尝试从 /etc/resolv.conf 读取 nameserver"
    local ip=""
    if ip=$(timeout 3 grep -m1 '^nameserver' /etc/resolv.conf 2>/dev/null | awk '{print $2}' | head -1); then
        log 3 "原始 IP: '$ip'"
        
        # 验证 IP 格式
        if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ && "$ip" != "127.0.0.53" ]]; then
            log 2 "✓ 成功获取 Windows IP: $ip"
            echo "$ip"
            return 0
        else
            log 3 "IP 格式无效或为 127.0.0.53,尝试备用方案"
        fi
    else
        log 3 "grep 超时或失败"
    fi
    
    # 方法2: 尝试 host.docker.internal
    log 3 "尝试从 host.docker.internal 获取 IP"
    if command -v getent >/dev/null 2>&1; then
        if ip=$(timeout 3 getent hosts host.docker.internal 2>/dev/null | awk '{print $1}' | head -1); then
            if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
                log 2 "✓ 通过 host.docker.internal 获取 IP: $ip"
                echo "$ip"
                return 0
            fi
        fi
    fi
    
    log 1 "❌ 无法获取 Windows 主机 IP"
    log 1 "诊断信息:"
    log 1 "  - /etc/resolv.conf 内容:"
    cat /etc/resolv.conf 2>/dev/null | head -5 | sed 's/^/    /' >&2 || echo "    ❌ 无法读取" >&2
    log 1 "  - 当前网络接口:"
    ip addr show eth0 2>/dev/null | grep "inet " | sed 's/^/    /' >&2 || echo "    ❌ 无 eth0 接口" >&2
    return 1
}

# ==================== 代理配置(关键:避免 sudo 卡住) ====================

proxy-on() {
    log 2 "=== 启动 proxy-on (PID: $$) ==="
    
    # 检查 sudo 是否需要密码(提前提示)
    log 2 "→ 检查 sudo 权限..."
    if ! timeout 3 sudo -n true 2>/dev/null; then
        log 1 "⚠️  sudo 需要密码!请在下方输入密码(输入时无回显):"
        if ! timeout 15 sudo -v 2>/dev/null; then
            log 1 "❌ sudo 密码验证超时或失败,退出"
            return 1
        fi
        log 2 "✓ sudo 权限已获取"
    else
        log 2 "✓ sudo 无需密码(已缓存)"
    fi
    
    # 获取 Windows IP
    local WIN_IP=""
    if ! WIN_IP=$(get_windows_host_ip); then
        log 1 "❌ 获取 Windows IP 失败,终止配置"
        return 1
    fi
    
    local PORT=${PROXY_PORT:-7890}
    log 2 "→ Windows 代理地址: $WIN_IP:$PORT"
    
    # 设置环境变量
    log 2 "→ 配置环境变量..."
    export http_proxy="http://$WIN_IP:$PORT"
    export https_proxy="http://$WIN_IP:$PORT"
    export HTTP_PROXY="http://$WIN_IP:$PORT"
    export HTTPS_PROXY="http://$WIN_IP:$PORT"
    export all_proxy="socks5://$WIN_IP:$PORT"
    export ALL_PROXY="socks5://$WIN_IP:$PORT"
    export no_proxy="localhost,127.0.0.1,::1,.local,.internal,$WIN_IP"
    export NO_PROXY="localhost,127.0.0.1,::1,.local,.internal,$WIN_IP"
    log 2 "✓ 环境变量已设置"
    
    # 配置 APT(最可能卡住的 sudo 操作)
    log 2 "→ 配置 APT 代理..."
    if command -v apt >/dev/null 2>&1; then
        log 3 "执行: sudo mkdir -p /etc/apt/apt.conf.d"
        if ! timeout 5 sudo mkdir -p /etc/apt/apt.conf.d 2>/dev/null; then
            log 1 "❌ sudo mkdir 超时,可能卡在密码输入"
            return 1
        fi
        
        log 3 "写入代理配置到 /etc/apt/apt.conf.d/80proxy"
        cat <<EOF | timeout 5 sudo tee /etc/apt/apt.conf.d/80proxy > /dev/null
Acquire::http::Proxy "$http_proxy";
Acquire::https::Proxy "$https_proxy";
EOF
        log 2 "✓ APT 代理配置完成"
    else
        log 3 "⚠️  apt 未安装,跳过"
    fi
    
    # 配置 Git(非阻塞)
    if command -v git >/dev/null 2>&1; then
        log 2 "→ 配置 Git 代理..."
        git config --global http.proxy "$http_proxy" 2>/dev/null || log 3 "⚠️  Git http.proxy 配置失败"
        git config --global https.proxy "$https_proxy" 2>/dev/null || log 3 "⚠️  Git https.proxy 配置失败"
        log 2 "✓ Git 代理配置完成"
    else
        log 3 "⚠️  git 未安装,跳过"
    fi
    
    # 配置 NPM(非阻塞)
    if command -v npm >/dev/null 2>&1; then
        log 2 "→ 配置 NPM 代理..."
        npm config set proxy "$http_proxy" 2>/dev/null || log 3 "⚠️  NPM proxy 配置失败"
        npm config set https-proxy "$https_proxy" 2>/dev/null || log 3 "⚠️  NPM https-proxy 配置失败"
        log 2 "✓ NPM 代理配置完成"
    else
        log 3 "⚠️  npm 未安装,跳过"
    fi
    
    # 跳过 Docker 检测(易卡住)
    log 3 "⚠️  跳过 Docker 检测(避免 docker info 阻塞)"
    
    log 2 "=== proxy-on 执行完成 ==="
    echo ""
    echo "✅ 代理已启用: $http_proxy"
    echo "💡 提示: 确保 Windows 代理软件已开启【允许局域网连接】"
}

# ==================== 快速诊断命令 ====================

proxy-diagnose() {
    echo "=========================================="
    echo "WSL2 代理环境诊断报告"
    echo "生成时间: $(date)"
    echo "=========================================="
    echo ""
    
    echo "1. /etc/resolv.conf 状态:"
    echo "------------------------------------------"
    ls -la /etc/resolv.conf 2>&1 || echo "❌ 无法访问"
    echo ""
    cat /etc/resolv.conf 2>&1 | head -10 || echo "❌ 无法读取内容"
    echo ""
    
    echo "2. Windows 主机 IP 检测:"
    echo "------------------------------------------"
    grep -m1 nameserver /etc/resolv.conf 2>&1 || echo "❌ 未找到 nameserver"
    echo ""
    
    echo "3. 网络连通性测试:"
    echo "------------------------------------------"
    ip addr show eth0 2>&1 | grep "inet " || echo "❌ 无 eth0 接口"
    echo ""
    
    echo "4. sudo 权限检测:"
    echo "------------------------------------------"
    if sudo -n true 2>/dev/null; then
        echo "✓ sudo 无需密码(已缓存)"
    else
        echo "⚠️  sudo 需要密码(可能卡住脚本)"
    fi
    echo ""
    
    echo "5. 代理端口可达性测试 (7890):"
    echo "------------------------------------------"
    local win_ip=$(grep -m1 nameserver /etc/resolv.conf | awk '{print $2}' 2>/dev/null)
    if [[ -n "$win_ip" && "$win_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        echo "Windows IP: $win_ip"
        timeout 3 bash -c "echo > /dev/tcp/$win_ip/7890" 2>&1 && echo "✓ 端口可达" || echo "❌ 端口不可达"
    else
        echo "❌ 无法获取有效 Windows IP"
    fi
    echo ""
    
    echo "=========================================="
    echo "常见问题解决方案:"
    echo "------------------------------------------"
    echo "❌ 问题1: 脚本卡在 sudo"
    echo "   → 方案: 执行 'sudo -v' 提前输入密码,或配置免密:"
    echo "      echo '$(whoami) ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/wsl-proxy"
    echo ""
    echo "❌ 问题2: /etc/resolv.conf 被锁定"
    echo "   → 方案: sudo chattr -i /etc/resolv.conf"
    echo ""
    echo "❌ 问题3: 无法获取 Windows IP"
    echo "   → 方案: 重启 WSL (Windows PowerShell: wsl --shutdown)"
    echo "=========================================="
}

# 快捷命令
alias po="proxy-on"
alias pd="proxy-diagnose"

log 2 "✅ 调试版代理脚本已加载"
log 2 "可用命令: proxy-on (po) | proxy-diagnose (pd)"
  1. 保存脚本并赋予执行权限
mkdir -p ~/bin
cat > ~/bin/proxy.sh << 'EOF'
# 粘贴上方完整脚本内容
EOF
chmod +x ~/bin/proxy.sh
  1. 永久生效(添加到 ~/.bashrc)
echo -e "\n# WSL2 代理管理" >> ~/.bashrc
echo 'source ~/bin/proxy.sh' >> ~/.bashrc
source ~/.bashrc
  1. 一键启用代理
proxy-on
# 或简写
po