适用于windows。复制所有代码在powershell管理员运行就可以了。
很简单自己研究一下,懒得写教程
如果得到点鸡腿的话,把支持linux mac alpine上的也一起分享了
$GithubApiUrl = "https://api.github.com/repos/EasyTier/EasyTier/releases/latest"$GithubProxy = "gh.cococ.co" # 可选代理, 留空则不使用$InstallDir = "$env:ProgramFiles\EasyTier"$ConfigDir = "$env:ProgramData\EasyTier"$ConfigFile = Join-Path $ConfigDir "easytier.toml"$CoreBinaryName = "easytier-core.exe"$CliBinaryName = "easytier-cli.exe"$CoreBinaryPath = Join-Path $InstallDir $CoreBinaryName$CliBinaryPath = Join-Path $InstallDir $CliBinaryName# --- Windows 服务定义 ---$ServiceName = "EasyTierService"$ServiceDisplayName = "EasyTier Service"# --- 颜色定义 ---$c_green = "Green"$c_red = "Red"$c_yellow = "Yellow"$c_cyan = "Cyan"$c_normal = "White"# --- 辅助函数 ---# 检查是否以管理员身份运行function Check-Admin { $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = [System.Security.Principal.WindowsPrincipal]::new($identity) if (-not $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Host "错误: 此脚本必须以管理员身份运行。" -ForegroundColor $c_red Write-Host "请右键点击 PowerShell 窗口标题栏,选择 '以管理员身份运行',或右键点击脚本文件选择 '使用 PowerShell 运行'。" -ForegroundColor $c_yellow Read-Host "按 Enter 键退出..." exit 1 }}# 检查 EasyTier 是否已安装function Check-Installed { if (-not (Test-Path $CoreBinaryPath)) { Write-Host "EasyTier 尚未安装。请先选择选项 1。" -ForegroundColor $c_yellow return $false } return $true}# 修改 toml 文件中的值 (PowerShell 版本)function Set-TomlValue { param( [string]$Key, [string]$Value, [string]$FilePath ) try { $content = Get-Content $FilePath -Raw $pattern = "(?im)^#*\s*($Key)\s*=.+" $replacement = "$Key = $Value" $newContent = $content -replace $pattern, $replacement Set-Content -Path $FilePath -Value $newContent } catch { Write-Host "错误: 修改配置文件失败: $_" -ForegroundColor $c_red }}# --- 主功能函数 ---function Install-EasyTier { Write-Host "--- 开始安装或更新 EasyTier ---" -ForegroundColor $c_green # 在 Windows 上,我们主要关注 x86_64 $arch = "x86_64" $os_identifier = "windows" Write-Host "1. 获取最新版本信息..." try { $latestInfo = Invoke-RestMethod -Uri $GithubApiUrl } catch { Write-Host "错误: 无法从 GitHub API 获取版本信息。请检查网络连接。" -ForegroundColor $c_red return } $search_prefix = "easytier-${os_identifier}-${arch}" $asset = $latestInfo.assets | Where-Object { $_.name -like "$search_prefix*.zip" } if (-not $asset) { Write-Host "错误: 未能找到适用于 Windows (x64) 的包。" -ForegroundColor $c_red return } $downloadUrl = $asset.browser_download_url $fileName = $asset.name $version = $latestInfo.tag_name Write-Host "检测到版本: $version, 架构: $arch, 文件: $fileName" if ($GithubProxy) { $downloadUrl = "https://$GithubProxy/$downloadUrl" Write-Host "2. 使用代理下载: $downloadUrl" -ForegroundColor $c_yellow } else { Write-Host "2. 直接下载: $downloadUrl" } $tempFile = Join-Path $env:TEMP $fileName try { Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile -UseBasicParsing } catch { Write-Host "下载失败! $_" -ForegroundColor $c_red if (Test-Path $tempFile) { Remove-Item $tempFile } return } Write-Host "3. 解压并安装..." # 确保安装目录存在 if (-not (Test-Path $InstallDir)) { New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null } try { Expand-Archive -Path $tempFile -DestinationPath $InstallDir -Force } catch { Write-Host "解压失败! $_" -ForegroundColor $c_red if (Test-Path $tempFile) { Remove-Item $tempFile } return } # ====================【关键修复代码块】==================== Write-Host "4. 整理文件结构..." -ForegroundColor $c_yellow # 查找解压后可能创建的子目录 (例如 easytier-windows-x86_64) $subDir = Get-ChildItem -Path $InstallDir -Directory | Select-Object -First 1 if ($subDir) { # 如果找到了子目录,将其中的所有内容移动到上层安装目录 Write-Host "检测到子目录 $($subDir.FullName),正在移动文件..." -ForegroundColor $c_cyan Move-Item -Path (Join-Path $subDir.FullName "*") -Destination $InstallDir -Force # 删除空的子目录 Remove-Item -Path $subDir.FullName -Force -ErrorAction SilentlyContinue } # ========================================================= # 清理工作 Remove-Item $tempFile Write-Host "--- EasyTier $version 安装/更新成功! ---" -ForegroundColor $c_green Write-Host "程序已安装到: $InstallDir" -ForegroundColor $c_cyan # 如果服务已存在, 重启以应用更新 if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) { Write-Host "检测到现有服务,正在重启以应用更新..." -ForegroundColor $c_yellow Restart-Service -Name $ServiceName }}function Create-DefaultConfig { if (-not (Test-Path $ConfigDir)) { New-Item -Path $ConfigDir -ItemType Directory -Force | Out-Null }$configContent = @"# === EasyTier 配置文件 (由脚本生成) ===ipv4 = ""dhcp = falselisteners = ["udp://0.0.0.0:11010", "tcp://0.0.0.0:11010", "wg://0.0.0.0:11011", "ws://0.0.0.0:11011/", "wss://0.0.0.0:11012/"][network_identity]network_name = ""network_secret = ""[flags]default_protocol = "udp"dev_name = ""enable_encryption = trueenable_ipv6 = truemtu = 1380latency_first = trueenable_exit_node = falseno_tun = falseuse_smoltcp = falseforeign_network_whitelist = "*"disable_p2p = falserelay_all_peer_rpc = falsedisable_udp_hole_punching = falseenableKcp_Proxy = true"@ Set-Content -Path $ConfigFile -Value $configContent Write-Host "已成功创建默认配置文件: $ConfigFile"}function Configure-Network { if (-not (Check-Installed)) { return } $network_name = Read-Host "请输入网络名称" $network_secret = Read-Host "请输入网络密钥" $virtual_ip = Read-Host "请输入此节点虚拟IP (留空则启用DHCP)" $is_client = Read-Host "是否要连接到一个现有的对端节点? (y/n)" Create-DefaultConfig Set-TomlValue "network_name" "`"$network_name`"" $ConfigFile Set-TomlValue "network_secret" "`"$network_secret`"" $ConfigFile if ([string]::IsNullOrWhiteSpace($virtual_ip)) { Write-Host "未输入IP,将启用 DHCP 自动获取地址。" -ForegroundColor $c_yellow Set-TomlValue "dhcp" "true" $ConfigFile Set-TomlValue "ipv4" "`"`"" $ConfigFile } else { Write-Host "已设置静态IP: $virtual_ip" -ForegroundColor $c_green Set-TomlValue "dhcp" "false" $ConfigFile Set-TomlValue "ipv4" "`"$virtual_ip`"" $ConfigFile } if ($is_client -eq 'y') { $peer_address = Read-Host "请输入一个对端节点地址 (如 tcp://服务器IP:11010)" Add-Content -Path $ConfigFile -Value "`n[[peer]]`nuri = `"$peer_address`"" } Write-Host "正在创建并配置 Windows 服务..." -ForegroundColor $c_yellow # 如果服务存在, 先删除旧的, 以确保配置更新 if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) { Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue # 使用 sc.exe delete 比 Remove-Service 更可靠 sc.exe delete $ServiceName | Out-Null Start-Sleep -Seconds 2 } # 创建服务 $binaryPathWithArgs = "`"$CoreBinaryPath`" -c `"$ConfigFile`"" New-Service -Name $ServiceName -BinaryPathName $binaryPathWithArgs -DisplayName $ServiceDisplayName -StartupType Automatic # *** 关键:配置服务失败后自动重启,实现进程守护 *** # 第一次/第二次/后续失败后, 都在5秒后重启 sc.exe failure $ServiceName reset=86400 actions=restart/5000/restart/5000/restart/5000 | Out-Null Write-Host "服务创建成功,正在启动..." -ForegroundColor $c_green Start-Service -Name $ServiceName Start-Sleep -Seconds 2 Get-Service -Name $ServiceName | Format-List -Property Name, DisplayName, Status, StartType}function Manage-Service { if (-not (Check-Installed)) { return } if (-not (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue)) { Write-Host "服务尚未创建。请先配置网络 (选项 2)。" -ForegroundColor $c_yellow return } $menu_title = "管理EasyTier服务" $options = @( "启动服务", "停止服务", "重启服务", "查看状态", "返回主菜单" ) while ($true) { Clear-Host Write-Host "================ $menu_title ================" -ForegroundColor $c_cyan Get-Service -Name $ServiceName | Format-List -Property Name, DisplayName, Status, StartType Write-Host "------------------------------------------------" -ForegroundColor $c_cyan for ($i = 0; $i -lt $options.Count; $i++) { Write-Host ("{0}. {1}" -f ($i+1), $options[$i]) } $choice = Read-Host "请选择操作" switch ($choice) { '1' { Start-Service -Name $ServiceName; Write-Host "服务已启动。" -ForegroundColor $c_green } '2' { Stop-Service -Name $ServiceName; Write-Host "服务已停止。" -ForegroundColor $c_green } '3' { Restart-Service -Name $ServiceName; Write-Host "服务已重启。" -ForegroundColor $c_green } '4' { # 状态已在顶部显示,这里刷新一次 Get-Service -Name $ServiceName | Format-List -Property Name, DisplayName, Status, StartType } '5' { return } default { Write-Host "无效输入" -ForegroundColor $c_red } } Read-Host "按 Enter 键继续..." }}function Uninstall-EasyTier { Write-Host "警告: 此操作将停止服务并删除所有相关文件和配置。" -ForegroundColor $c_yellow $confirm = Read-Host "确定要卸载吗? (y/n)" if ($confirm -ne 'y') { Write-Host "操作已取消。" return } Write-Host "正在停止并删除服务..." if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) { Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue sc.exe delete $ServiceName | Out-Null Start-Sleep -Seconds 2 # 等待服务删除完成 } Write-Host "正在删除文件和目录..." if (Test-Path $InstallDir) { Remove-Item -Path $InstallDir -Recurse -Force } if (Test-Path $ConfigDir) { Remove-Item -Path $ConfigDir -Recurse -Force } Write-Host "EasyTier 已成功卸载。" -ForegroundColor $c_green}# --- 主菜单循环 ---function Show-MainMenu { Check-Admin while ($true) { Clear-Host Write-Host "=======================================================" -ForegroundColor $c_cyan Write-Host " EasyTier 跨平台部署脚本 (Windows Edition)" -ForegroundColor $c_green Write-Host "=======================================================" -ForegroundColor $c_cyan Write-Host " 1. 安装或更新 EasyTier" Write-Host " 2. 配置网络并安装服务 (首次设置)" Write-Host "-------------------------------------------------------" Write-Host " 3. 管理 EasyTier 服务状态" Write-Host " 4. 查看 EasyTier 配置文件" Write-Host " 5. 查看 EasyTier 网络节点" Write-Host "-------------------------------------------------------" Write-Host " 6. 卸载 EasyTier" Write-Host " 0. 退出脚本" Write-Host "=======================================================" -ForegroundColor $c_cyan $choice = Read-Host "请输入选项 [0-6]" switch ($choice) { '1' { Install-EasyTier } '2' { Configure-Network } '3' { Manage-Service } '4' { if ((Check-Installed) -and (Test-Path $ConfigFile)) { Clear-Host Get-Content $ConfigFile | Write-Host } else { Write-Host "配置文件不存在或未安装。" -ForegroundColor $c_yellow } } '5' { if (Check-Installed) { Clear-Host & $CliBinaryPath peer } } '6' { Uninstall-EasyTier } '0' { exit 0 } default { Write-Host "无效输入" -ForegroundColor $c_red } } Write-Host "" Read-Host "按任意键返回主菜单..." }}# --- 脚本入口 ---Show-MainMenu
评论 (0)