# ========================================== # 🖥️ SYSTEM UTILS # ========================================== # --- СИСТЕМНАЯ ИНФОРМАЦИЯ --- function Get-HWID { param([string]$StoreDir) $hwidFile = "$StoreDir\hwid" if (Test-Path $hwidFile) { return (Get-Content $hwidFile -Raw).Trim() } $hwid = [System.Guid]::NewGuid().ToString("N").Substring(0, 16) if (!(Test-Path $StoreDir)) { New-Item -ItemType Directory -Path $StoreDir -Force | Out-Null } Set-Content -Path $hwidFile -Value $hwid return $hwid } function Get-SystemInfo { return @{ os = "windows" version = [System.Environment]::OSVersion.Version.Major.ToString() } } # --- DOCKER --- function Test-Docker { $status = @{ Installed = $false Running = $false Compose = $false } try { $ver = docker --version 2>&1 if ($LASTEXITCODE -eq 0) { $status.Installed = $true } } catch {} if ($status.Installed) { try { $info = docker info 2>&1 if ($LASTEXITCODE -eq 0) { $status.Running = $true } } catch {} } if ($status.Running) { try { $comp = docker compose version 2>&1 if ($LASTEXITCODE -eq 0) { $status.Compose = $true } } catch { # Check legacy try { $comp = docker-compose --version 2>&1 if ($LASTEXITCODE -eq 0) { $status.Compose = $true } } catch {} } } return $status } # --- СЛУЖБЫ И ЗАДАЧИ --- function Manage-ScheduledTask { param( [string]$Name, [string]$ExePath, [string]$Arguments, [string]$WorkDir, [string]$Action = "Install" # Install, Uninstall, Start, Stop ) switch ($Action) { "Install" { # Удаляем старую Unregister-ScheduledTask -TaskName $Name -Confirm:$false -ErrorAction SilentlyContinue $act = New-ScheduledTaskAction -Execute "$ExePath" -Argument "$Arguments" -WorkingDirectory $WorkDir $trig = New-ScheduledTaskTrigger -AtStartup $princ = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest $sett = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) Register-ScheduledTask -TaskName $Name -Action $act -Trigger $trig -Principal $princ -Settings $sett -Force | Out-Null return $true } "Uninstall" { Unregister-ScheduledTask -TaskName $Name -Confirm:$false -ErrorAction SilentlyContinue } "Start" { Start-ScheduledTask -TaskName $Name -ErrorAction SilentlyContinue } "Stop" { Stop-ScheduledTask -TaskName $Name -ErrorAction SilentlyContinue # Пытаемся убить процесс по имени exe if ($ExePath) { $procName = [System.IO.Path]::GetFileNameWithoutExtension($ExePath) if ($procName) { Stop-Process -Name $procName -Force -ErrorAction SilentlyContinue } } } } } function Get-TaskStatus { param([string]$Name) $task = Get-ScheduledTask -TaskName $Name -ErrorAction SilentlyContinue if ($task) { # Если задача в статусе Running — возвращаем Running if ($task.State -eq "Running") { return "Running" } # Если задача Ready — проверяем, работает ли процесс sing-box # (scheduled task может быть Ready даже когда процесс работает) $process = Get-Process -Name "sing-box" -ErrorAction SilentlyContinue if ($process) { return "Running" } return $task.State } return $null } function Ensure-FirewallPort { param( [int]$Port, [string]$Name, [string]$Protocol = "TCP" ) $rule = Get-NetFirewallRule -DisplayName $Name -ErrorAction SilentlyContinue if (-not $rule) { New-NetFirewallRule -DisplayName $Name -Direction Inbound -LocalPort $Port -Protocol $Protocol -Action Allow -Profile Any | Out-Null return $true } return $false } function Get-LocalIPs { return (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias * | Where-Object { $_.IPAddress -notmatch "^127\." -and $_.IPAddress -notmatch "^169\.254\." }).IPAddress }