From d686c8721f6d4aaa8027d9acfae952117be8ff4d Mon Sep 17 00:00:00 2001 From: dawn-lc <30336566+dawn-lc@users.noreply.github.com> Date: Thu, 4 Dec 2025 23:06:06 +0800 Subject: [PATCH] feat(install): enhance installation script functionality (#1641) * feat(install): enhance installation script functionality * fix temp file extname --- script/install.cmd | 1177 +++++++++++++++++++++--------------------- script/uninstall.cmd | 2 - 2 files changed, 583 insertions(+), 596 deletions(-) delete mode 100644 script/uninstall.cmd diff --git a/script/install.cmd b/script/install.cmd index 8367626..2242bee 100644 --- a/script/install.cmd +++ b/script/install.cmd @@ -2,47 +2,187 @@ @ECHO off SETLOCAL EnableDelayedExpansion TITLE Initializing Script... -CD /d %~dp0 -SET ScriptPath=\^"%~f0\^" -SET ScriptRoot=%~dp0 -SET ScriptRoot=\^"!ScriptRoot:~0,-1!\^" -SET Args=%* -IF DEFINED Args (SET Args=!Args:"=\"!) +CD /d %~dp0 ]" } else { "[ ]" } - $color = if ($i -eq $highlightIndex) { "Green" } else { "Gray" } - Write-Host "$prefix $($options[$i])" -ForegroundColor $color -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($helps[$i])) { " - $($helps[$i])" } else { "" }) -ForegroundColor DarkGray - } - } - # 只更新变化的选项 - if ($prevIndex -ne -1) { - $safePrevPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $prevIndex) - [Console]::SetCursorPosition(0, $safePrevPos) - Write-Host "[ ] $($options[$prevIndex])" -ForegroundColor Gray -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($helps[$prevIndex])) { " - $($helps[$prevIndex])" } else { "" }) -ForegroundColor DarkGray - } - $safeHighlightPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $highlightIndex) - [Console]::SetCursorPosition(0, $safeHighlightPos) - Write-Host "[>] $($options[$highlightIndex])" -ForegroundColor Green -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($helps[$highlightIndex])) { " - $($helps[$highlightIndex])" } else { "" }) -ForegroundColor DarkGray - # 首次显示时绘制操作提示 - if ($prevIndex -eq -1) { - $safePos = [Math]::Min([Console]::WindowHeight - 2, $menuTop + $options.Count) - [Console]::SetCursorPosition(0, $safePos) - Write-Host "操作: 使用 ↑ / ↓ 移动 | Enter - 确认" - } - } - finally { - # 将光标移动到操作提示下方等待位置 - $waitPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $options.Count + 1) - [Console]::SetCursorPosition(0, $waitPos) - } - } - $prevSelection = -1 - while ($true) { - Show-Menu -highlightIndex $currentSelection -title $Title -message $Message -options $Options -helps $Helps -prevIndex $prevSelection - $prevSelection = $currentSelection - $key = [System.Console]::ReadKey($true) - switch ($key.Key) { - { $_ -eq [ConsoleKey]::UpArrow } { - $currentSelection = [Math]::Max(0, $currentSelection - 1) - } - { $_ -eq [ConsoleKey]::DownArrow } { - $currentSelection = [Math]::Min($Options.Count - 1, $currentSelection + 1) - } - { $_ -eq [ConsoleKey]::Enter } { - Clear-Host - return $currentSelection - } - } - } -} -function Show-MultiSelectPrompt { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true, Position = 0)] - [ValidateNotNullOrEmpty()] - [string]$Message, - [Parameter(Mandatory = $true, Position = 1)] - [ValidateNotNullOrEmpty()] - [string[]]$Options, - [string[]]$Helps = @(), - [string]$Title = "", - [int[]]$DefaultSelections = @() - ) - if ($Helps.Count -eq 0) { - $Helps = @("") - for ($i = 1; $i -lt $Options.Count; $i++) { - $Helps += "" - } - } - if ($Options.Count -ne $Helps.Count) { - throw "Options 和 Helps 的数量必须相同。" - } - $selectedIndices = [System.Collections.Generic.List[int]]::new($DefaultSelections) - $currentSelection = 0 - function Show-Menu { - param( - [int]$highlightIndex, - [System.Collections.Generic.List[int]]$selectedItems, - [int]$prevIndex = -1, - [int]$prevHighlight = -1 - ) - try { - # 首次显示时绘制完整菜单 - if ($prevIndex -eq -1) { - Clear-Host - if (-not [string]::IsNullOrEmpty($Title)) { - Write-Host "$Title`n" -ForegroundColor Blue - } - Write-Host "$Message" -ForegroundColor Yellow - # 保存初始光标位置 - $script:menuTop = [Console]::CursorTop - # 首次绘制所有选项 - for ($i = 0; $i -lt $Options.Count; $i++) { - $isSelected = $selectedItems -contains $i - $prefix = if ($isSelected) { "[#]" } else { "[ ]" } - $color = if ($i -eq $highlightIndex) { "Green" } elseif ($isSelected) { "Cyan" } else { "Gray" } - Write-Host "$prefix $($Options[$i])" -ForegroundColor $color -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($Helps[$i])) { " - $($Helps[$i])" } else { "" }) -ForegroundColor DarkGray - } - } - # 只更新变化的选项 - if ($prevIndex -ne -1) { - $safePrevPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $prevIndex) - [Console]::SetCursorPosition(0, $safePrevPos) - $isPrevSelected = $selectedItems -contains $prevIndex - $prefix = if ($isPrevSelected) { "[#]" } else { "[ ]" } - Write-Host "$prefix $($Options[$prevIndex])" -ForegroundColor $(if ($isPrevSelected) { "Cyan" } else { "Gray" }) -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($Helps[$prevIndex])) { " - $($Helps[$prevIndex])" } else { "" }) -ForegroundColor DarkGray - } - if ($prevHighlight -ne -1 -and $prevHighlight -ne $highlightIndex) { - $safePrevHighlightPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $prevHighlight) - [Console]::SetCursorPosition(0, $safePrevHighlightPos) - $isPrevHighlightSelected = $selectedItems -contains $prevHighlight - $prefix = if ($isPrevHighlightSelected) { "[#]" } else { "[ ]" } - Write-Host "$prefix $($Options[$prevHighlight])" -ForegroundColor $(if ($isPrevHighlightSelected) { "Cyan" } else { "Gray" }) -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($Helps[$prevHighlight])) { " - $($Helps[$prevHighlight])" } else { "" }) -ForegroundColor DarkGray - } - $safeHighlightPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $highlightIndex) - [Console]::SetCursorPosition(0, $safeHighlightPos) - $isSelected = $selectedItems -contains $highlightIndex - $prefix = if ($isSelected) { "[#]" } else { "[ ]" } - Write-Host "$prefix $($Options[$highlightIndex])" -ForegroundColor "Green" -NoNewline - Write-Host $(if (-not [string]::IsNullOrEmpty($Helps[$highlightIndex])) { " - $($Helps[$highlightIndex])" } else { "" }) -ForegroundColor DarkGray - # 首次显示时绘制操作提示 - if ($prevIndex -eq -1) { - $safePos = [Math]::Min([Console]::WindowHeight - 2, $menuTop + $Options.Count) - [Console]::SetCursorPosition(0, $safePos) - Write-Host "操作: 使用 ↑ / ↓ 移动 | Space - 选中/取消 | Enter - 确认" - } - } - finally { - # 将光标移动到操作提示下方等待位置 - $waitPos = [Math]::Min([Console]::WindowHeight - 1, $menuTop + $Options.Count + 1) - [Console]::SetCursorPosition(0, $waitPos) - } - } - $prevSelection = -1 - $prevHighlight = -1 - while ($true) { - Show-Menu -highlightIndex $currentSelection -selectedItems $selectedIndices -prevIndex $prevSelection -prevHighlight $prevHighlight - $prevHighlight = $currentSelection - $key = [System.Console]::ReadKey($true) - switch ($key.Key) { - { $_ -eq [ConsoleKey]::UpArrow } { - $prevSelection = $currentSelection - $currentSelection = [Math]::Max(0, $currentSelection - 1) - } - { $_ -eq [ConsoleKey]::DownArrow } { - $prevSelection = $currentSelection - $currentSelection = [Math]::Min($Options.Count - 1, $currentSelection + 1) - } - { $_ -eq [ConsoleKey]::Spacebar } { - $prevSelection = $currentSelection - if ($selectedIndices.Contains($currentSelection)) { - $selectedIndices.Remove($currentSelection) - } - else { - $selectedIndices.Add($currentSelection) - } - } - { $_ -eq [ConsoleKey]::Enter } { - Clear-Host - return $selectedIndices - } - } - } -} function Get-InputWithNoNullOrWhiteSpace { [CmdletBinding()] param( @@ -298,12 +225,9 @@ function Get-InputWithNoNullOrWhiteSpace { try { $response = Read-Host "请输入${Prompt}(必填)" if ([string]::IsNullOrWhiteSpace($response)) { - Write-Host "${Prompt}不能为空!" -ForegroundColor Red + Write-Host "${Prompt}不能为空!" -ForegroundColor Red continue } - if ($response -match '^(?!").*(? $null 2>&1 + } +} +function Get-SystemArchitecture { + try { + $platform = [System.Environment]::OSVersion.Platform + if ($platform -ne [System.PlatformID]::Win32NT) { + throw "Unsupported OS: Non-Windows platform detected ($platform)" + } + } + catch { + throw "Unsupported OS: Unable to determine platform." + } + if ($env:PROCESSOR_ARCHITEW6432) { + $arch = $env:PROCESSOR_ARCHITEW6432 + } + else { + $arch = $env:PROCESSOR_ARCHITECTURE + } + switch ($arch) { + "AMD64" { return "windows-x86_64" } + "ARM64" { return "windows-arm64" } + "x86" { return "windows-i686" } + default { throw "Unsupported architecture: windows-$arch" } + } +} +function Get-LocalVersion { + param([string]$CorePath) + if (-not (Test-Path $CorePath)) { + Write-Host "未找到本地程序!" -ForegroundColor Yellow + return [System.Version]"0.0.0" + } + try { + $versionOutput = & $CorePath --version 2>$null + if ($versionOutput -match "easytier-core\s+([0-9]+\.[0-9]+\.[0-9]+)") { + return [System.Version]$matches[1] + } + else { + throw "无法解析返回值: $versionOutput" + } + } + catch { + throw "获取本地版本失败`n$_" + } +} +function Get-RemoteVersion { + param([PSCustomObject]$response) + try { + return [System.Version]$response.tag_name.TrimStart("v") + } + catch { + throw "无法从 GitHub 获取最新版本信息`n$response" + } +} +function Get-EasyTier { + $Arch = Get-SystemArchitecture + + $tempDirectory = Join-Path $ScriptRoot "easytier_update" + + try { + if (-not (Test-Path $tempDirectory)) { + New-Item -ItemType Directory -Path $tempDirectory | Out-Null + } + } + catch { + throw "无法创建文件夹 $tempDirectory`n$_" + } + + try { + Write-Host "检查最新版本..." -ForegroundColor Green + $response = Invoke-RestMethodCompatible -Uri "https://api.github.com/repos/EasyTier/EasyTier/releases/latest" + $latestVersion = Get-RemoteVersion($response) + } + catch { + throw "获取最新版本失败。请检查网络连接或API请求达到上限`n$_" + } + + $localVersion = Get-LocalVersion($EasyTierPath) + if ($localVersion -ge $latestVersion) { + Write-Host "EasyTier 已是最新版本 $localVersion" -ForegroundColor Green + return + } + + $asset = $response.assets | Where-Object { $_.name -like "easytier-$Arch*.zip" } | Select-Object -First 1 + if ($asset) { + Write-Output "发现新版本 $latestVersion" + $downloadUrl = $asset.browser_download_url + if ($UseGitHubProxy) { + $downloadUrl = "$GitHubProxy$downloadUrl" + } + } + else { + throw "未适配当前平台!" + } + + $updateFile = Join-Path $tempDirectory $asset.name + + try { + Write-Output "开始下载: $downloadUrl" + Invoke-WebRequestCompatible -Uri $downloadUrl -OutFile $updateFile + } + catch { + throw "下载失败!`n$_" + } + + try { + Expand-ZipFile -ZipPath $updateFile -DestinationPath $tempDirectory + $extractedRoot = Get-ChildItem -Path $tempDirectory -Directory | Select-Object -First 1 + $updateFileDirectory = $extractedRoot.FullName + } + catch { + throw "解压失败!`n$_" + } + + Write-Host "准备就绪,开始更新..." -ForegroundColor Green + + $activeServices = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Running" } + if ($activeServices) { + try { + Write-Host "发现正在运行的服务: $ServiceName" -ForegroundColor Yellow + Write-Host "停止 EasyTier 服务..." -ForegroundColor Yellow + $activeServices | Stop-Service -Force + } + catch { + throw "停止服务失败!`n$_" + } + } + + try { + Write-Host "更新文件..." + Get-ChildItem -Path $updateFileDirectory | Copy-Item -Destination $ScriptRoot -Recurse -Force + } + catch { + throw "更新文件失败!`n$_" + } + + $localVersion = Get-LocalVersion($EasyTierPath) + if ($localVersion -ge $latestVersion) { + if ($activeServices) { + try { + Write-Host "启动服务..." -ForegroundColor Green + $activeServices | Start-Service + } + catch { + throw "服务启动失败!`n$_" + } + } + Write-Host "EasyTier 已成功更新到版本 $latestVersion" -ForegroundColor Green + } + else { + throw "更新文件失败! 请检查脚本是否过时或者文件/文件夹是否被其他程序占用" + } + Remove-Item -Recurse -Force $tempDirectory +} + +$HelpText = @" +EasyTier 服务管理脚本 + +【使用方式】 +直接双击运行或在命令行中执行: + + install.cmd [参数] + +【可用参数】 + + -H / -? / -Help + 显示此帮助信息并退出。 + + -U / -Update + 更新 EasyTier 到最新版本 + + -X / -Uninstall + 卸载 EasyTier 服务 + + -UGHP / -UseGitHubProxy + 使用 GitHub 镜像代理下载 (默认: $false) + + -GHP / -GitHubProxy <代理地址> + 指定 GitHub 镜像代理地址 (默认: https://ghfast.top/) + + -UP / -UseProxy + 使用自定义代理 (默认: $false) + + -P / -Proxy <代理地址> + 指定自定义代理地址 (默认: http://127.0.0.1:7890) + + -C / -ConfigType <类型> + 指定配置模式,可选值: + * File 本地配置文件 + * Remote 远程服务器集中管理 + * CLI 使用命令行直接传参 + + -N / -ServiceName <名称> + 指定安装的服务名称 (默认: EasyTierService) + + <其他参数...> + 当选择 CLI 模式时,用于传递自定义参数 + +【运行要求】 + * 已安装 PowerShell 3.0 或更高版本 + * 管理员权限 (自动检测并可请求提升) + +【配置模式说明】 + 1. File 模式: + 从指定的本地配置文件加载运行参数 + 脚本会提示输入配置文件路径 (可拖入文件) + + 2. Remote 模式: + 从服务器集中管理配置,可输入自定义管理服务器地址 + (例如: udp://x.x.x.x:22020/admin) + + 3. CLI 模式: + 直接通过命令行参数传递任意配置 + +【代理设置说明】 + * UseGitHubProxy 和 UseProxy 参数不能同时使用 + * 使用 GitHub 镜像代理可加速下载 + +【示例】 + 1. 使用本地配置文件安装: + install.cmd -ConfigType File + + 2. 使用远程服务器并设定服务名称: + install.cmd -ConfigType Remote -ServiceName EasyTierService + + 3. 使用命令行传参: + install.cmd -ConfigType CLI --ipv4 x.x.x.x --network-name xxx --network-secret yyy --peers tcp://peer_host:11010 + + 4. 使用 GitHub 镜像代理更新: + install.cmd -Update -UseGitHubProxy + + 5. 使用系统代理安装: + install.cmd -UseProxy -Proxy http://127.0.0.1:8080 + + 6. 卸载服务: + install.cmd -Uninstall + + 7. 显示帮助信息: + install.cmd -Help +"@ +$WatchDogTemplate = @" + + + $((Get-Date).ToString("s")) + \EasyTierWatchDog + + + + true + <QueryList><Query Id="0" Path="System"><Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and EventID=107]]</Select></Query></QueryList> + + + true + <QueryList><Query Id="0" Path="Microsoft-Windows-WLAN-AutoConfig/Operational"><Select Path="Microsoft-Windows-WLAN-AutoConfig/Operational">*[System[Provider[@Name='Microsoft-Windows-WLAN-AutoConfig'] and EventID=8001]]</Select></Query></QueryList> + + + + + SYSTEM + HighestAvailable + + + + IgnoreNew + false + false + true + true + true + + + + cmd.exe + /c "net stop %#ServiceName#% & net start %#ServiceName#%" + + + +"@ + +$host.ui.rawui.WindowTitle = "安装/卸载/更新 EasyTier 服务" Clear-Host $ScriptRoot = (Get-Location).Path -$ServicesPath = Join-Path $ScriptRoot "services" -$RequiredFiles = @("easytier-core.exe", "easytier-cli.exe", "nssm.exe", "Packet.dll", "wintun.dll") -foreach ($file in $RequiredFiles) { - if (-not (Test-Path (Join-Path $ScriptRoot $file))) { - Write-Host "缺少必要文件: ${file}" -ForegroundColor Red - Show-Pause -Text "按任意键退出..." - exit 1 - } -} +$RegistryPath = "HKLM:\SOFTWARE\EasyTierServiceManage" +$RegistryName = "Services" +$EasyTierPath = Join-Path $ScriptRoot "easytier-core.exe" +$OPTIONS = @() + +$ErrorActionPreference = "Stop" try { - $nssm = Join-Path $ScriptRoot "nssm.exe" + if ($Help) { + Write-Host $HelpText + Show-Pause -Text "按任意键退出..." + exit 0 + } + if ($UseProxy -and $UseGitHubProxy) { + throw "UseProxy 和 UseGitHubProxy 参数不能同时使用,请选择其中一种代理方式。" + } if ($Uninstall) { - $Force = $false - $Action = "designation" - if (-not (Test-ServiceNameExists -FilePath $ServicesPath -ServiceName $ServiceName)) { + $services = Get-ServiceNames + if ($services.Count -lt 1 -and (-not (Test-ServiceNameExists -Name $ServiceName))) { Write-Host "服务未安装" -ForegroundColor Red - if (Show-YesNoPrompt -Message "是否强制卸载?" -DefaultIndex 1) { - $Force = $true - $Action = "all" + if (Show-YesNoPrompt -Message "是否尝试强制卸载?" -DefaultIndex 1) { + Write-Host "正在停止服务 $ServiceName ..." + Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue + Write-Host "正在移除服务 $ServiceName ..." + Remove-ServiceCompatible -Name "$ServiceName" -ErrorAction SilentlyContinue + Remove-ServiceName -Name $ServiceName -ErrorAction SilentlyContinue + Write-Host "服务 $ServiceName 已卸载" -ForegroundColor Green + } + } + else { + foreach ($service in $services) { + if (Get-Service -Name $service -ErrorAction SilentlyContinue) { + Write-Host "正在停止服务 $service ..." + Stop-Service -Name $service -Force + Write-Host "正在移除服务 $service ..." + Remove-ServiceCompatible -Name "$service" + Remove-ServiceName -Name $service + } + Write-Host "服务 $service 已卸载" -ForegroundColor Green + } + } + Show-Pause -Text "按任意键退出..." + Unregister-ScheduledTask -TaskName "EasyTierWatchDog" -Confirm:$false -ErrorAction SilentlyContinue | Out-Null + exit 0 + } + if ($Update) { + Get-EasyTier + Show-Pause -Text "按任意键退出..." + exit 0 + } + if (-not (Test-Path $EasyTierPath)) { + Get-EasyTier + } + if (-not $ConfigType) { + $choices = @( + [System.Management.Automation.Host.ChoiceDescription]::new("&File", "本地配置文件"), + [System.Management.Automation.Host.ChoiceDescription]::new("&Remote", "服务器集中管理"), + [System.Management.Automation.Host.ChoiceDescription]::new("&CLI", "命令行传参") + ) + $selected = $Host.UI.PromptForChoice("您准备如何配置EasyTier?", "请选择: ", $choices, 0) + $ConfigType = @("File", "Remote", "CLI")[$selected] + } + switch ($ConfigType) { + "File" { + $OPTIONS += "--config-file $(Get-InputWithFileValidation -Prompt "配置文件路径(或将文件拖动到此处)")" + } + "Remote" { + if (Show-YesNoPrompt -Message "是否使用自定义管理服务器?" -DefaultIndex 1) { + $configServer = Get-InputWithNoNullOrWhiteSpace -Prompt "自定义管理服务器(格式: 协议://IP:端口/用户)" } else { - Show-Pause -Text "按任意键退出..." - exit 1 + $configServer = Get-InputWithNoNullOrWhiteSpace -Prompt "官方服务器用户名" + } + $OPTIONS += "--config-server $configServer" + } + "CLI" { + if (-not $ServiceArgs -or $ServiceArgs.Count -eq 0) { + $OPTIONS += Get-InputWithNoNullOrWhiteSpace -Prompt "自定义启动参数" + } + else { + $OPTIONS += $ServiceArgs } } - # 参数处理 - if ($Action -eq "all") { - if (-not $Force) { - if (-not (Show-YesNoPrompt -Message "确定要完全卸载所有服务吗?" -DefaultIndex 1)) { - Write-Host "已取消卸载操作" -ForegroundColor Yellow - Show-Pause -Text "按任意键退出..." - exit 0 - } - } - Write-Host "正在卸载所有服务..." -ForegroundColor Cyan - # 读取所有服务名 - $services = Get-Content $ServicesPath | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } - if (-not $services) { - $services = @($ServiceName) - } + default { + throw "未知配置类型: $ConfigType" } - else { - $services = @($ServiceName) + } + $BinaryPath = "`"$EasyTierPath`" $($OPTIONS -join ' ')" + Write-Host "生成的配置参数如下: " -ForegroundColor Yellow + Write-Host ($OPTIONS -join " ") -ForegroundColor DarkGray + if (Show-YesNoPrompt -Message "确认安装配置?" -DefaultIndex 1) { + if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) { + Stop-Service -Name $ServiceName -Force | Out-Null + Remove-ServiceCompatible -Name $ServiceName } - foreach ($service in $services) { - # 停止服务 - Write-Host "正在停止服务 $service ..." - & $nssm stop $service - # 删除服务(自动确认) - Write-Host "正在移除服务 $service ..." - & $nssm remove $service confirm - Remove-ServiceName -FilePath $ServicesPath -ServiceName $service - Write-Host "服务 $service 已卸载" -ForegroundColor Green - } - # 如果是完全卸载,删除服务记录文件 - if ($Action -eq "all") { - Remove-Item $ServicesPath -Force - Write-Host "已删除服务列表文件" -ForegroundColor Green - } - } - else { - $OPTIONS = Get-EasyTierConfig - $arguments = $OPTIONS -join ' ' - Write-Host "生成的配置参数如下:" -ForegroundColor Yellow - Write-Host ($OPTIONS -join " ") -ForegroundColor DarkGray - if (Show-YesNoPrompt -Message "确认安装配置?" -DefaultIndex 1) { - & $nssm install $ServiceName (Join-Path $ScriptRoot "easytier-core.exe") - & $nssm set $ServiceName AppParameters $arguments - & $nssm set $ServiceName Description "EasyTier 核心服务" - & $nssm set $ServiceName AppDirectory $ScriptRoot - & $nssm set $ServiceName Start SERVICE_AUTO_START - & $nssm start $ServiceName - Save-ServiceName -FilePath $ServicesPath -ServiceName $ServiceName - Write-Host "服务安装完成。" -ForegroundColor Green - } - else { - Write-Host "安装已取消。" -ForegroundColor Yellow - } - } + New-Service -Name $ServiceName -DisplayName "EasyTier" ` + -Description "EasyTier 核心服务" ` + -StartupType Automatic ` + -BinaryPathName $BinaryPath | Out-Null + Start-Service -Name $ServiceName | Out-Null + + Register-ScheduledTask -TaskName "EasyTierWatchDog" -User "SYSTEM" -Xml $WatchDogTemplate.Replace("%#ServiceName#%", $ServiceName) -Force | Out-Null + Save-ServiceName -Name $ServiceName + Write-Host "安装完成。" -ForegroundColor Green + } + else { + Write-Host "安装已取消。" -ForegroundColor Yellow + } + Show-Pause -Text "按任意键退出..." } catch { - Write-Host "$($host.ui.rawui.WindowTitle)发生错误: $_" -ForegroundColor Red + Write-Host "发生错误: $_" -ForegroundColor Red + Show-Pause -Text "按任意键退出..." + Unregister-ScheduledTask -TaskName "EasyTierWatchDog" -Confirm:$false -ErrorAction SilentlyContinue exit 1 } -Show-Pause -Text "按任意键退出..." -exit + diff --git a/script/uninstall.cmd b/script/uninstall.cmd deleted file mode 100644 index 73a3599..0000000 --- a/script/uninstall.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -install.cmd -Uninstall %* \ No newline at end of file