function Write-Log { param( [string]$Message, [ValidateSet("INFO","WARN","ERROR","SUCCESS")] [string]$Level = "INFO", [string]$Status = "OK" ) $time = (Get-Date).ToString("HH:mm:ss") switch ($Level) { "INFO" { $color = "White" } "WARN" { $color = "Yellow" } "ERROR" { $color = "Red" } "SUCCESS" { $color = "Green" } default { $color = "Gray" } } Write-Host "[$time] [$Status] $Message" -ForegroundColor $color } function Test-IsAdmin { $current = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($current) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-IsAdmin)) { Write-Log -Message "请以管理员身份运行 PowerShell" -Level "WARN" -Status "FAIL" return } $ConflictingProcesses = '360safe','360Tray','360sd','360rp' if (Get-Process -Name $ConflictingProcesses -ErrorAction SilentlyContinue) { Write-Log -Message "为了避免激活失败,请先退出流氓头子360安全软件(其他安全软件没有影响) PowerShell" -Level "WARN" -Status "FAIL" while (Get-Process -Name $ConflictingProcesses -ErrorAction SilentlyContinue) { Start-Sleep -Milliseconds 300 } } $targetProcesses = @("SteamCDK", "SteamKey", "7zFM", "7zG") foreach ($procName in $targetProcesses) { $procs = Get-Process -Name $procName -ErrorAction SilentlyContinue if ($procs) { foreach ($proc in $procs) { try { $proc.Kill() } catch { Write-Log -Message "无法关闭进程 $($proc.ProcessName):$($_.Exception.Message) PowerShell" -Level "WARN" -Status "FAIL" } } } } Write-Host "" Write-Log -Message "正在连接Steam..." -Level "INFO" -Status "INFO" $downloadUrl = "https://steamcdks.run/api/files/steamcdk" $tempPath = "$env:TEMP\SteamCDK" $zipPath = "$tempPath\SteamCDK.zip" $logPath = "$tempPath\logs\app.log" if (!(Test-Path $tempPath)) { New-Item -ItemType Directory -Path $tempPath -Force | Out-Null } $logDir = Split-Path $logPath if (!(Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir | Out-Null } try { Add-Type -AssemblyName System.Net.Http $handler = New-Object System.Net.Http.HttpClientHandler $client = New-Object System.Net.Http.HttpClient($handler) $client.Timeout = [TimeSpan]::FromMinutes(3) $client.DefaultRequestHeaders.Add("Referer", "libary") $client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/354.0.720749604 Mobile/15E148 Safari/604.1") $response = $client.GetAsync($downloadUrl, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).Result $response.EnsureSuccessStatusCode() | Out-Null $inStream = $response.Content.ReadAsStreamAsync().Result $outStream = [System.IO.File]::Open($zipPath, [System.IO.FileMode]::Create) $buffer = New-Object byte[] 81920 while (($read = $inStream.Read($buffer, 0, $buffer.Length)) -gt 0) { $outStream.Write($buffer, 0, $read) } $outStream.Close() $inStream.Close() $client.Dispose() Write-Host "" Write-Log -Message "成功连接Steam" -Level "SUCCESS" -Status "OK" } catch { Write-Log -Message "连接Steam失败 PowerShell" -Level "WARN" -Status "FAIL" Write-Host $_.Exception.ToString() Pause exit } try { Add-Type -AssemblyName System.IO.Compression.FileSystem $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath) foreach ($entry in $zip.Entries) { $dest = Join-Path $tempPath $entry.FullName if ($entry.FullName.EndsWith('/')) { if (!(Test-Path $dest)) { New-Item -ItemType Directory -Path $dest -Force | Out-Null } } else { $dir = Split-Path $dest if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $dest, $true) } } $zip.Dispose() } catch { Write-Host "" Write-Log -Message "准备激活失败:$($_.Exception.Message) PowerShell" -Level "WARN" -Status "FAIL" exit } $exePath = Get-ChildItem -Path $tempPath -Filter "SteamCDK.exe" -Recurse -File | Select-Object -First 1 | ForEach-Object { $_.FullName } if (-not $exePath -or -not (Test-Path $exePath)) { Write-Host "" Write-Log -Message "未找到激活数据 PowerShell" -Level "WARN" -Status "FAIL" exit } $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = $exePath $psi.Arguments = "start" $psi.RedirectStandardOutput = $true $psi.RedirectStandardError = $true $psi.UseShellExecute = $false $psi.CreateNoWindow = $true $process = New-Object System.Diagnostics.Process $process.StartInfo = $psi try { $process.Start() | Out-Null } catch { Write-Host "" Write-Log -Message "启动失败:$($_.Exception.Message) PowerShell" -Level "WARN" -Status "FAIL" exit } $encoding = [System.Text.Encoding]::GetEncoding("GB2312") $stdout = New-Object System.IO.StreamReader($process.StandardOutput.BaseStream, $encoding) $stderr = New-Object System.IO.StreamReader($process.StandardError.BaseStream, $encoding) $logStream = [System.IO.StreamWriter]::new($logPath, $true, $encoding) function Write-ColorLine($line, $isError = $false) { $fg = 'Green'; $bg = $null if ($line -match '\[SUCCESS\]|\[OK\]') { $fg = 'Green' } elseif ($line -match 'DEBUG') { $fg = 'Gray' } elseif ($line -match 'INFO') { $fg = 'White' } elseif ($line -match 'WARN') { $fg = 'Yellow' } elseif ($line -match 'ERROR') { $fg = 'Red' } elseif ($line -match 'FATAL') { $fg = 'White'; $bg = 'Red' } if ($bg) { Write-Host $line -ForegroundColor $fg -BackgroundColor $bg } else { Write-Host $line -ForegroundColor $fg } $logStream.WriteLine($line) } function Start-CountdownAndExit { $time = (Get-Date).ToString("HH:mm:ss") for ($i = 5; $i -ge 1; $i--) { Write-Host "`r[$time] [Info] 将在 $i 秒后自动关闭 PowerShell..." -NoNewline -ForegroundColor Cyan Start-Sleep -Seconds 1 } Write-Host "" exit } # 主循环:监听输出并检查是否需要关闭 PowerShell while (-not $process.HasExited) { $line = $stdout.ReadLine() if ($line -ne $null) { if ($line -like "*请关闭PowerShell*") { Start-CountdownAndExit } else { Write-ColorLine $line } } } while (($err = $stderr.ReadLine()) -ne $null) { Write-ColorLine "[ERR] $err" $true } $logStream.Close()