hostSync/install.ps1

331 lines
9.9 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 使用方法: irm "https://git.xykqyy.com/ljp/hostSync/raw/branch/main/install.ps1" | iex
# 设置严格模式和错误处理
Set-StrictMode -Version 3.0
$ErrorActionPreference = 'Stop'
# 默认配置
$Version = 'latest'
$InstallDir = "$env:USERPROFILE\.hostsync\bin"
$NoInit = $false
$Portable = $false
# 颜色输出函数
function Write-ColorOutput {
param([string]$Message, [string]$Color = 'White')
Write-Host $Message -ForegroundColor $Color
}
function Write-Success { param([string]$Message) Write-ColorOutput $Message 'Green' }
function Write-Info { param([string]$Message) Write-ColorOutput $Message 'Cyan' }
function Write-Warning { param([string]$Message) Write-ColorOutput $Message 'Yellow' }
function Write-Error { param([string]$Message) Write-ColorOutput $Message 'Red' }
# 检查管理员权限
function Test-Administrator {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
# 获取最新版本
function Get-LatestVersion {
try {
Write-Info '? 获取最新版本信息...'
$api = 'https://git.xykqyy.com/api/v1/repos/ljp/hostSync/releases/latest'
$response = Invoke-RestMethod -Uri $api -ErrorAction Stop
return $response.tag_name
}
catch {
Write-Warning '?? 无法获取最新版本,使用 v1.0.0'
return 'v1.0.0'
}
}
# 检测系统架构
function Get-Architecture {
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
'AMD64' { return 'amd64' }
'x86' { return '386' }
'ARM64' { return 'arm64' }
default { return 'amd64' }
}
}
# 下载文件
function Get-FileFromUrl {
param([string]$Url, [string]$Output)
Write-Info "? 下载: $(Split-Path $Output -Leaf)"
Write-Info "? 地址: $Url"
try {
# 使用 Invoke-WebRequest 下载
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $Url -OutFile $Output -ErrorAction Stop
$ProgressPreference = 'Continue'
if (Test-Path $Output) {
$size = [math]::Round((Get-Item $Output).Length / 1MB, 2)
Write-Success "? 下载完成 ($size MB)"
return $true
}
}
catch {
Write-Error "? IWR 下载失败: $($_.Exception.Message)"
# 尝试使用 curl 作为备用方案
Write-Info '? 尝试使用 curl...'
try {
$curlArgs = @('-L', $Url, '-o', $Output, '--silent', '--show-error')
$curlProcess = Start-Process -FilePath 'curl.exe' -ArgumentList $curlArgs -Wait -PassThru -WindowStyle Hidden
if ($curlProcess.ExitCode -eq 0 -and (Test-Path $Output)) {
Write-Success '? 使用 curl 下载完成'
return $true
}
else {
Write-Error "? curl 退出码: $($curlProcess.ExitCode)"
}
}
catch {
Write-Error "? curl 执行失败: $($_.Exception.Message)"
}
}
return $false
}
# 检查并卸载已有服务
function Remove-ExistingService {
Write-Info '? 检查现有安装...'
# 检查 PATH 中的 hostsync
$existingPath = $null
$pathDirs = $env:PATH -split ';'
foreach ($dir in $pathDirs) {
$testPath = Join-Path $dir 'hostsync.exe'
if (Test-Path $testPath) {
$existingPath = $testPath
break
}
}
# 检查默认安装位置
if (-not $existingPath) {
$defaultPath = "$env:USERPROFILE\.hostsync\bin\hostsync.exe"
if (Test-Path $defaultPath) {
$existingPath = $defaultPath
}
}
if ($existingPath) {
Write-Info "? 发现现有安装: $existingPath"
try {
# 尝试停止并卸载服务
Write-Info '?? 停止现有服务...'
$stopArgs = @{
FilePath = $existingPath
ArgumentList = @('service', 'stop')
Wait = $true
PassThru = $true
RedirectStandardOutput = $true
RedirectStandardError = $true
WindowStyle = 'Hidden'
}
Start-Process @stopArgs | Out-Null
Write-Info '?? 卸载现有服务...'
$uninstallArgs = @{
FilePath = $existingPath
ArgumentList = @('service', 'uninstall')
Wait = $true
PassThru = $true
RedirectStandardOutput = $true
RedirectStandardError = $true
WindowStyle = 'Hidden'
}
Start-Process @uninstallArgs | Out-Null
Write-Success '? 已清理现有服务'
}
catch {
Write-Warning "?? 清理现有服务时出现错误: $($_.Exception.Message)"
Write-Info '? 继续安装过程...'
}
# 等待一下确保服务完全停止
Start-Sleep -Seconds 2
}
else {
Write-Info '? 未发现现有安装'
}
}
# 主安装函数
function Install-HostSync {
Write-ColorOutput @'
? HostSync 快速安装脚本
===============================
强大的 Hosts 文件管理工具
功能特点:
- ? 分块管理 Hosts 配置
- ? 智能 DNS 解析
- ? 定时自动更新
- ? 后台服务运行
'@ 'Magenta'
# 检查并卸载已有服务
Remove-ExistingService
# 检查管理员权限
if (-not (Test-Administrator)) {
Write-Warning '?? 未检测到管理员权限,将跳过服务安装'
Write-Info '? 如需安装服务,请稍后以管理员身份运行: hostsync service install'
$NoInit = $true
}
# 确定版本
if ($Version -eq 'latest') {
$Version = Get-LatestVersion
}
Write-Info "? 安装版本: $Version"# 处理版本号格式 - 确保有v前缀用于tag去掉v前缀用于文件名
$TagVersion = $Version
$FileVersion = $Version
if ($Version -match '^v(\d+\.\d+\.\d+)$') {
$TagVersion = $Version
$FileVersion = $matches[1]
}
elseif ($Version -match '^(\d+\.\d+\.\d+)$') {
$TagVersion = "v$Version"
$FileVersion = $Version
}
# 确定架构
$Arch = Get-Architecture
Write-Info "?? 系统架构: $Arch" # 确定安装目录 (固定为默认位置)
Write-Info "? 安装目录: $InstallDir"
# 创建安装目录
if (-not (Test-Path $InstallDir)) {
try {
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Write-Success '? 创建安装目录'
}
catch {
Write-Error "? 创建目录失败: $($_.Exception.Message)"
exit 1
}
} # 构建下载 URL
$FileName = "hostsync-$FileVersion-windows-$Arch.exe"
$DownloadUrl = "https://git.xykqyy.com/ljp/hostSync/releases/download/$TagVersion/$FileName"
$OutputFile = Join-Path $InstallDir 'hostsync.exe' # 下载文件
if (-not (Get-FileFromUrl $DownloadUrl $OutputFile)) {
Write-Error '? 下载失败,请检查网络连接或手动下载'
Write-Info '? 手动下载地址: https://git.xykqyy.com/ljp/hostSync/releases'
exit 1
}
# 验证文件
if (-not (Test-Path $OutputFile)) {
Write-Error '? 安装文件不存在'
exit 1
}
Write-Success '? HostSync 下载完成!' # 添加到 PATH
Write-Info '? 配置环境变量...'
try {
$currentPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if ($currentPath -notlike "*$InstallDir*") {
$newPath = "$currentPath;$InstallDir"
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
Write-Success '? 已添加到 PATH 环境变量'
Write-Warning '?? 请重启终端以生效环境变量'
}
else {
Write-Info '? PATH 已包含安装目录'
}
}
catch {
Write-Warning "?? 设置环境变量失败: $($_.Exception.Message)"
Write-Info "? 你可以手动将 '$InstallDir' 添加到 PATH"
}# 运行初始化
if (-not $NoInit) {
Write-Info '? 开始初始化 HostSync...'
try {
# 使用 Start-Process 来更好地控制进程执行
Write-Info "? 执行命令: $OutputFile init"
$processArgs = @{
FilePath = $OutputFile
ArgumentList = @('init')
Wait = $true
PassThru = $true
RedirectStandardOutput = $true
RedirectStandardError = $true
WindowStyle = 'Hidden'
}
$process = Start-Process @processArgs
if ($process.ExitCode -eq 0) {
Write-Success '? 初始化完成!'
}
else {
Write-Warning "?? 初始化退出码: $($process.ExitCode)"
Write-Info '? 可能需要管理员权限,你可以稍后手动运行:'
Write-Info ' 以管理员身份打开 PowerShell'
Write-Info ' 运行: hostsync init'
}
}
catch {
Write-Warning "?? 初始化过程出现异常: $($_.Exception.Message)"
Write-Info '? 请尝试手动初始化:'
Write-Info ' 1. 以管理员身份打开 PowerShell'
Write-Info " 2. 运行: `"$OutputFile`" init"
Write-Info ' 3. 或者: hostsync init (如果已添加到PATH)'
}
}
# 显示完成信息
Write-Success @"
? HostSync !
=====================
? : $OutputFile
? : $env:USERPROFILE\.hostsync\
? :
"@
Write-Info ' hostsync list # 查看配置'
Write-Info ' hostsync add test example.com # 添加域名'
Write-Info @'
hostsync update # 更新解析
hostsync service status # 查看服务状态
? 更多帮助:
hostsync help # 查看帮助
hostsync version # 查看版本
? 项目地址: https://git.xykqyy.com/ljp/hostSync
'@
}
# 错误处理
trap {
Write-Error "? 安装过程中发生错误: $($_.Exception.Message)"
Write-Info '? 请检查网络连接或手动下载安装'
exit 1
}
# 执行安装
Remove-ExistingService
Install-HostSync