Загрузка данных


@echo off
setlocal
set "BAT_FILE=%~f0"

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$p=$env:BAT_FILE; $m='### POWERSHELL START ###'; $t=[System.IO.File]::ReadAllText($p,[System.Text.Encoding]::Default); $i=$t.IndexOf($m); if($i -lt 0){throw 'PowerShell part not found'}; $code=$t.Substring($i+$m.Length); Invoke-Expression $code"

if errorlevel 1 (
    echo.
    echo Script finished with an error.
    pause
)

exit /b


### POWERSHELL START ###

$ErrorActionPreference = "Stop"

Add-Type -AssemblyName System.Windows.Forms

Add-Type @"
using System;
using System.Text;
using System.Runtime.InteropServices;

public class WinApi {
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, UInt32 uFlags);
}
"@

function Quote-Arg {
    param([string]$Text)
    return '"' + $Text.Replace('"', '\"') + '"'
}

function Show-Error {
    param([string]$Message)
    [System.Windows.Forms.MessageBox]::Show($Message, "Launcher error") | Out-Null
}

function Move-Window {
    param(
        [IntPtr]$Handle,
        [int]$X,
        [int]$Y,
        [int]$Width,
        [int]$Height
    )

    if ($Handle -eq [IntPtr]::Zero) {
        return $false
    }

    $SW_RESTORE = 9
    $SWP_NOZORDER = 0x0004
    $SWP_SHOWWINDOW = 0x0040

    [void][WinApi]::ShowWindow($Handle, $SW_RESTORE)
    [void][WinApi]::SetWindowPos($Handle, [IntPtr]::Zero, $X, $Y, $Width, $Height, $SWP_NOZORDER -bor $SWP_SHOWWINDOW)

    return $true
}

function Move-NewProcessWindow {
    param(
        [string[]]$ProcessNames,
        [datetime]$After,
        [int]$X,
        [int]$Y,
        [int]$Width,
        [int]$Height
    )

    for ($i = 0; $i -lt 80; $i++) {
        Start-Sleep -Milliseconds 250

        $candidates = @()

        foreach ($name in $ProcessNames) {
            $items = Get-Process -Name $name -ErrorAction SilentlyContinue

            foreach ($p in $items) {
                try {
                    if ($p.MainWindowHandle -ne 0 -and $p.StartTime -ge $After.AddSeconds(-5)) {
                        $candidates += $p
                    }
                }
                catch {
                }
            }
        }

        $win = $candidates | Sort-Object StartTime -Descending | Select-Object -First 1

        if ($win) {
            return Move-Window -Handle $win.MainWindowHandle -X $X -Y $Y -Width $Width -Height $Height
        }
    }

    return $false
}

function Find-Chrome {
    $pf86 = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)")

    $paths = @(
        "$env:ProgramFiles\Google\Chrome\Application\chrome.exe",
        "$pf86\Google\Chrome\Application\chrome.exe",
        "$env:LocalAppData\Google\Chrome\Application\chrome.exe"
    )

    foreach ($path in $paths) {
        if ($path -and (Test-Path -LiteralPath $path)) {
            return $path
        }
    }

    $cmd = Get-Command "chrome.exe" -ErrorAction SilentlyContinue | Select-Object -First 1

    if ($cmd) {
        return $cmd.Source
    }

    return $null
}

function Find-PythonForIdle {
    $pf86 = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)")

    $patterns = @(
        "$env:LocalAppData\Programs\Python\Python*\pythonw.exe",
        "$env:ProgramFiles\Python*\pythonw.exe",
        "$pf86\Python*\pythonw.exe",
        "$env:LocalAppData\Programs\Python\Python*\python.exe",
        "$env:ProgramFiles\Python*\python.exe",
        "$pf86\Python*\python.exe"
    )

    $found = @()

    foreach ($pattern in $patterns) {
        $found += Get-ChildItem -Path $pattern -ErrorAction SilentlyContinue
    }

    $best = $found | Sort-Object FullName -Descending | Select-Object -First 1

    if ($best) {
        return @{
            Exe = $best.FullName
            Prefix = @()
        }
    }

    $pyw = Get-Command "pyw.exe" -ErrorAction SilentlyContinue | Select-Object -First 1

    if ($pyw -and $pyw.Source -notlike "*\WindowsApps\*") {
        return @{
            Exe = $pyw.Source
            Prefix = @("-3")
        }
    }

    $py = Get-Command "py.exe" -ErrorAction SilentlyContinue | Select-Object -First 1

    if ($py -and $py.Source -notlike "*\WindowsApps\*") {
        return @{
            Exe = $py.Source
            Prefix = @("-3")
        }
    }

    $pythonw = Get-Command "pythonw.exe" -ErrorAction SilentlyContinue | Select-Object -First 1

    if ($pythonw -and $pythonw.Source -notlike "*\WindowsApps\*") {
        return @{
            Exe = $pythonw.Source
            Prefix = @()
        }
    }

    $python = Get-Command "python.exe" -ErrorAction SilentlyContinue | Select-Object -First 1

    if ($python -and $python.Source -notlike "*\WindowsApps\*") {
        return @{
            Exe = $python.Source
            Prefix = @()
        }
    }

    return $null
}

try {
    $screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea

    $leftX = $screen.X
    $topY = $screen.Y
    $halfWidth = [int]($screen.Width / 2)
    $height = $screen.Height
    $rightX = $screen.X + $halfWidth

    $desktop = [Environment]::GetFolderPath("Desktop")
    $projects = Join-Path $desktop "Projects"

    if (!(Test-Path -LiteralPath $projects)) {
        New-Item -ItemType Directory -Path $projects | Out-Null
    }

    $logFile = Join-Path $projects "launcher_log.txt"
    Add-Content -LiteralPath $logFile -Value ("--- " + (Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " ---")

    $date = Get-Date -Format "yyyy-MM-dd"
    $counter = 1

    do {
        $pyFile = Join-Path $projects ("{0}_{1}.py" -f $date, $counter)
        $counter++
    } while (Test-Path -LiteralPath $pyFile)

    New-Item -ItemType File -Path $pyFile | Out-Null
    Add-Content -LiteralPath $logFile -Value ("Created file: " + $pyFile)

    $chrome = Find-Chrome

    if (!$chrome) {
        throw "Google Chrome was not found."
    }

    Add-Content -LiteralPath $logFile -Value ("Chrome: " + $chrome)

    $chromeStart = Get-Date

    Start-Process -FilePath $chrome -ArgumentList @(
        "--new-window",
        "--window-position=$leftX,$topY",
        "--window-size=$halfWidth,$height",
        "https://kompege.ru"
    ) | Out-Null

    Move-NewProcessWindow -ProcessNames @("chrome") -After $chromeStart -X $leftX -Y $topY -Width $halfWidth -Height $height | Out-Null

    $pythonInfo = Find-PythonForIdle

    if (!$pythonInfo) {
        throw "Python with IDLE was not found. Install Python from python.org and enable 'Add Python to PATH'."
    }

    Add-Content -LiteralPath $logFile -Value ("Python/launcher: " + $pythonInfo.Exe)

    $idleStart = Get-Date

    $idleArgsArray = @()
    $idleArgsArray += $pythonInfo.Prefix
    $idleArgsArray += "-m"
    $idleArgsArray += "idlelib"
    $idleArgsArray += Quote-Arg $pyFile

    $idleArgs = $idleArgsArray -join " "

    Start-Process -FilePath $pythonInfo.Exe -ArgumentList $idleArgs | Out-Null

    $movedIdle = Move-NewProcessWindow -ProcessNames @("pythonw", "python", "pyw", "py") -After $idleStart -X $rightX -Y $topY -Width $halfWidth -Height $height

    Add-Content -LiteralPath $logFile -Value ("Moved IDLE window: " + $movedIdle)
}
catch {
    $msg = $_.Exception.Message

    try {
        if ($projects) {
            Add-Content -LiteralPath $logFile -Value ("ERROR: " + $msg)
        }
    }
    catch {
    }

    Show-Error $msg
    exit 1
}