# anydesk-run.ps1 — найти и запустить/показать AnyDesk (WP 5.1+)

[CmdletBinding()]
param(
    [switch]$AsAdmin,
    [switch]$ForceSearch
)

function Show-Message($text, $title = "AnyDesk") {
    try {
        Add-Type -AssemblyName System.Windows.Forms -ErrorAction SilentlyContinue
        [System.Windows.Forms.MessageBox]::Show($text, $title, 'OK', 'Information') | Out-Null
    } catch {
        Write-Host ("{0}: {1}" -f $title, $text)
    }
}

# --- Win32: поднять окно уже запущенного процесса (совместимо с PS 5.1) ---
$winApiCs = @"
using System;
using System.Runtime.InteropServices;
using System.Text;

public static class WinAPI {
    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
    [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd);
    [DllImport("user32.dll")] public static extern int  GetWindowTextLength(IntPtr hWnd);
    [DllImport("user32.dll")] public static extern int  GetWindowText(IntPtr hWnd, StringBuilder text, int count);
    [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    [DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"@
Add-Type -TypeDefinition $winApiCs -Language CSharp

function Bring-AnyDesk-ToFront {
    param([int]$ProcessId)

    $foundHwnd = [IntPtr]::Zero

    $cb = [WinAPI+EnumWindowsProc]{
        param([IntPtr]$hWnd, [IntPtr]$lParam)

        if (-not [WinAPI]::IsWindowVisible($hWnd)) { return $true }

        [uint32]$pid = 0
        [WinAPI]::GetWindowThreadProcessId($hWnd, [ref]$pid) | Out-Null
        if ($pid -ne [uint32]$ProcessId) { return $true }

        $foundHwnd = $hWnd
        return $false
    }

    [WinAPI]::EnumWindows($cb, [IntPtr]::Zero) | Out-Null

    if ($foundHwnd -ne [IntPtr]::Zero) {
        [WinAPI]::ShowWindowAsync($foundHwnd, 9) | Out-Null  # SW_RESTORE
        [WinAPI]::SetForegroundWindow($foundHwnd) | Out-Null
        return $true
    }
    return $false
}

# --- 1) Если уже запущен — поднять окно и выйти ---
try {
    $existing = Get-Process -Name 'AnyDesk' -ErrorAction SilentlyContinue | Select-Object -First 1
    if ($existing) {
        if (Bring-AnyDesk-ToFront -ProcessId $existing.Id) { return }
        # шанс «разбудить» UI через повторный вызов того же exe
        if ($existing.Path -and (Test-Path $existing.Path)) {
            try { Start-Process -FilePath $existing.Path | Out-Null; return } catch { }
        }
    }
} catch { }

# --- 2) Пути окружения ---
$pf     = [Environment]::GetEnvironmentVariable('ProgramFiles')
$pfx86  = [Environment]::GetEnvironmentVariable('ProgramFiles(x86)')
$pgdata = [Environment]::GetEnvironmentVariable('ProgramData')
$local  = [Environment]::GetEnvironmentVariable('LOCALAPPDATA')

# --- 3) Кандидаты стандартных путей ---
$candidates = @()
if ($pfx86) { $candidates += (Join-Path -Path $pfx86 -ChildPath 'AnyDesk\AnyDesk.exe') }
if ($pf)    { $candidates += (Join-Path -Path $pf    -ChildPath 'AnyDesk\AnyDesk.exe') }
if ($pgdata){ $candidates += (Join-Path -Path $pgdata -ChildPath 'AnyDesk\AnyDesk.exe') }
if ($local) { $candidates += (Join-Path -Path $local -ChildPath 'Programs\AnyDesk\AnyDesk.exe') }

# --- 4) App Paths (реестр) ---
foreach ($key in @(
    'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AnyDesk.exe',
    'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AnyDesk.exe'
)) {
    try {
        $val = (Get-ItemProperty -Path $key -ErrorAction SilentlyContinue).'(Default)'
        if ($val) { $candidates += $val }
    } catch { }
}

# --- 5) Первый реально существующий путь ---
$anydeskPath = $null
foreach ($c in $candidates) {
    if ($c -and (Test-Path $c)) { $anydeskPath = $c; break }
}

# --- 6) При необходимости — расширенный поиск по типовым корням ---
if (-not $anydeskPath -or $ForceSearch) {
    $roots = @()
    if ($pf)    { $roots += $pf }
    if ($pfx86) { $roots += $pfx86 }
    if ($pgdata){ $roots += $pgdata }
    if ($local) { $roots += (Join-Path -Path $local -ChildPath 'Programs') }

    foreach ($root in $roots) {
        try {
            if (-not $root) { continue }
            $found = Get-ChildItem -Path $root -Recurse -Filter 'AnyDesk*.exe' -File -Force -ErrorAction SilentlyContinue |
                     Select-Object -First 1 -ExpandProperty FullName
            if ($found) { $anydeskPath = $found; break }
        } catch { }
    }
}

# --- 7) Запуск или сообщение ---
if ($anydeskPath -and (Test-Path $anydeskPath)) {
    try {
        if ($AsAdmin) { Start-Process -FilePath $anydeskPath -Verb RunAs | Out-Null }
        else          { Start-Process -FilePath $anydeskPath              | Out-Null }
    } catch {
        Show-Message "Unable start AnyDesk: $($_.Exception.Message)"
        exit 1
    }
} else {
    Show-Message "Unable find AnyDesk on current pc."
    exit 2
}
