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


#donwloader.ps1
# --- 1. Проверка прав администратора ---
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    Write-Host "ОШИБКА: скрипт запущен без прав администратора!" -ForegroundColor Red
    Write-Host "Проверьте, что watcher запущен от имени администратора." -ForegroundColor Red
    Start-Sleep -Seconds 5
    exit 1
}

Write-Host "=== АВТОМАТИЧЕСКАЯ УСТАНОВКА/ПЕРЕУСТАНОВКА ПРОГРАММ ===" -ForegroundColor Cyan
Write-Host "Запущено от имени администратора" -ForegroundColor Green

# --- 2. Пути ---
# Папка-источник, где лежат KPE, PPK, KOE, KOEIZ
$rootFolder = "D:\win10\Share\App"

# --- Базовая папка: там, где лежит сам downloader.ps1 (= рядом с watcher.ps1) ---
$baseDir = $PSScriptRoot
if (-not $baseDir) {
    $baseDir = Split-Path -Parent $PSCommandPath
}
if (-not $baseDir) {
    $baseDir = Get-Location
}

# Рабочая папка = папка скрипта. Распаковываем прямо сюда.
$workBase = $baseDir

# Путь к WinRAR
$winRarPath = "C:\Program Files\WinRAR\WinRAR.exe"
if (!(Test-Path $winRarPath)) {
    $winRarPath = "C:\Program Files (x86)\WinRAR\WinRAR.exe"
}
if (!(Test-Path $winRarPath)) {
    Write-Host "ОШИБКА: WinRAR не найден по стандартным путям!" -ForegroundColor Red
    Write-Host "Укажите правильный путь в переменной `$winRarPath" -ForegroundColor Red
    Start-Sleep -Seconds 10
    exit 1
}

Write-Host "Папка-источник: $rootFolder" -ForegroundColor Cyan
Write-Host "Рабочая папка:  $workBase" -ForegroundColor Cyan
Write-Host "WinRAR:         $winRarPath" -ForegroundColor Cyan
Write-Host ""

# --- 3. Список программ ---
# Folder        — папка в $rootFolder (с архивом .rar)
# Name          — точное имя для Get-Package
# InstallFolder — имя папки в C:\Program Files (x86) (для запуска утилиты индексации)
$programs = @(
    @{ Folder = "KPE";   Name = "Клиент АИС Налог-3 Пром версия";     InstallFolder = "Ais3Prom" }
    @{ Folder = "PPK";   Name = "Клиент АИС Налог-3 ПредПром версия"; InstallFolder = "Ais3PredProm" }
    @{ Folder = "KOE";   Name = "Клиент АИС Налог-3 ОЭ версия";       InstallFolder = "Ais3FB3OE" }
    @{ Folder = "KOEIZ"; Name = "Клиент АИС Налог-3 ОЭ ИЗ версия";    InstallFolder = "Ais3OEIZ" }
)

# Поиск установленной программы
function Find-InstalledProgram {
    param([string]$exactName)

    Write-Host "Поиск программы: $exactName" -ForegroundColor Cyan

    $foundPackage = Get-Package -Name $exactName -ErrorAction SilentlyContinue |
        Select-Object -First 1

    if (-not $foundPackage) {
        $foundPackage = Get-Package -Name "*$exactName*" -ErrorAction SilentlyContinue |
            Select-Object -First 1
    }

    if ($foundPackage) {
        Write-Host "Программа найдена: $($foundPackage.Name) (v$($foundPackage.Version))" -ForegroundColor Green
    } else {
        Write-Host "Программа не найдена" -ForegroundColor Gray
    }

    return $foundPackage
}

# Удаление программы
function Uninstall-Program {
    param(
        [string]$displayName,
        $package
    )

    Write-Host "Удаление программы: $displayName" -ForegroundColor Yellow

    try {
        Uninstall-Package -InputObject $package -Force -ErrorAction Stop
        Write-Host "Удаление успешно завершено!" -ForegroundColor Green
        Start-Sleep -Seconds 3
    }
    catch {
        Write-Host "Ошибка при удалении: $($_.Exception.Message)" -ForegroundColor Red
    }
}

# --- Очистка рабочей папки: удаляем ВСЁ, кроме downloader.ps1 и watcher.ps1 ---
function Clear-WorkFolder {
    param([string]$FolderPath)

    if (-not (Test-Path $FolderPath)) {
        Write-Host "Папка для очистки не найдена: $FolderPath" -ForegroundColor Yellow
        return
    }

    Write-Host "Очистка рабочей папки (кроме downloader.ps1 и watcher.ps1): $FolderPath" -ForegroundColor Cyan

    try {
        Get-ChildItem -Path $FolderPath -Force -ErrorAction SilentlyContinue |
            Where-Object {
                $_.Name -ne "watcher.ps1" -and
                $_.Name -ne "downloader.ps1"
            } |
            ForEach-Object {
                Write-Host "   Удаление: $($_.FullName)" -ForegroundColor Gray
                Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
            }

        Write-Host "Очистка завершена (оставлены только downloader.ps1 и watcher.ps1)" -ForegroundColor Green
    }
    catch {
        Write-Host "Ошибка при очистке: $($_.Exception.Message)" -ForegroundColor Red
    }
}

# Очистка папки-источника, кроме .txt (маркер версии)
function Clear-FolderExceptTxt {
    param([string]$FolderPath)

    if (-not (Test-Path $FolderPath)) {
        Write-Host "Папка для очистки не найдена: $FolderPath" -ForegroundColor Yellow
        return
    }

    Write-Host "Очистка папки (кроме .txt): $FolderPath" -ForegroundColor Cyan

    try {
        Get-ChildItem -Path $FolderPath -Directory -Recurse -ErrorAction SilentlyContinue |
            ForEach-Object {
                Write-Host "   Удаление папки: $($_.FullName)" -ForegroundColor Gray
                Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
            }

        Get-ChildItem -Path $FolderPath -File -Recurse -ErrorAction SilentlyContinue |
            Where-Object { $_.Extension -ne ".txt" } |
            ForEach-Object {
                Write-Host "   Удаление файла: $($_.Name)" -ForegroundColor Gray
                Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
            }

        Write-Host "Очистка завершена (оставлены только .txt)" -ForegroundColor Green
    }
    catch {
        Write-Host "Ошибка при очистке: $($_.Exception.Message)" -ForegroundColor Red
    }
}

# Распаковка RAR через WinRAR
function Extract-RarArchive {
    param(
        [string]$archivePath,
        [string]$destinationPath
    )

    Write-Host "Распаковка: $archivePath" -ForegroundColor Cyan
    Write-Host "     в:    $destinationPath" -ForegroundColor Gray

    try {
        $arguments = "x -o+ -y `"$archivePath`" `"$destinationPath\`""
        $process = Start-Process -FilePath $winRarPath -ArgumentList $arguments -Wait -PassThru -NoNewWindow

        if ($process.ExitCode -eq 0) {
            Write-Host "Распаковка успешно завершена!" -ForegroundColor Green
            return $true
        } else {
            Write-Host "Ошибка распаковки! Код: $($process.ExitCode)" -ForegroundColor Red
            return $false
        }
    }
    catch {
        Write-Host "Ошибка при распаковке: $($_.Exception.Message)" -ForegroundColor Red
        return $false
    }
}

# --- Установка MSI + убийство процесса индексации + запуск утилиты ---
function Install-Program {
    param(
        [string]$msiPath,
        [string]$programName,
        [string]$installFolder
    )

    $processToKill = "CommonComponents.Catalog.IndexationUtility"
    $exeToRun      = "CommonComponents.Catalog.IndexationUtility.exe"

    Write-Host "Установка MSI: $msiPath" -ForegroundColor Cyan

    # --- Запуск msiexec ---
    $installArguments = "/i `"$msiPath`" /quiet"
    $installProcess = Start-Process -FilePath "msiexec.exe" `
        -ArgumentList $installArguments `
        -PassThru `
        -WindowStyle Hidden

    Write-Host "Установка запущена (PID: $($installProcess.Id))" -ForegroundColor Green

    # --- Ожидание появления процесса индексации и его убийство ---
    $targetProcess = $null
    $timeout = 1000
    $elapsed = 0

    Write-Host "Ожидание появления процесса $processToKill..." -ForegroundColor Cyan

    while ($elapsed -lt $timeout) {
        $targetProcess = Get-Process -Name $processToKill -ErrorAction SilentlyContinue

        if ($targetProcess) {
            Write-Host "Процесс $processToKill обнаружен!" -ForegroundColor Green
            Write-Host "Завершение процесса (PID: $($targetProcess.Id))..." -ForegroundColor Yellow
            Stop-Process -Id $targetProcess.Id -Force
            Write-Host "Процесс завершён." -ForegroundColor Green
            break
        }

        Start-Sleep -Seconds 2
        $elapsed += 2
    }

    if (-not $targetProcess) {
        Write-Host "Внимание: Процесс $processToKill не обнаружен" -ForegroundColor Red
    }

    # --- Ожидание завершения установки ---
    Write-Host "Ожидание завершения установки..." -ForegroundColor Cyan
    Wait-Process -Id $installProcess.Id -ErrorAction SilentlyContinue

    Write-Host "Установка MSI успешно завершена!" -ForegroundColor Green
    Write-Host "Установщик: $(Split-Path $msiPath -Leaf)" -ForegroundColor Green

    Start-Sleep -Seconds 3

    # --- Поиск папки программы по InstallFolder ---
    Write-Host "Поиск папки с установленной программой..." -ForegroundColor Cyan
    Write-Host "Ищем папку с именем $installFolder" -ForegroundColor Cyan

    $programsPath = "C:\Program Files (x86)"
    $programFolder = $null

    if (-not (Test-Path $programsPath)) {
        Write-Host "Внимание: Папка $programsPath не найдена" -ForegroundColor Red
    }
    else {
        # Сначала точное совпадение
        $programFolder = Get-ChildItem $programsPath -Directory -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -eq $installFolder } |
            Select-Object -First 1

        if (-not $programFolder) {
            Write-Host "Точное совпадение не найдено, ищем по частичному..." -ForegroundColor Yellow
            $programFolder = Get-ChildItem $programsPath -Directory -ErrorAction SilentlyContinue |
                Where-Object { $_.Name -like "*$installFolder*" } |
                Select-Object -First 1
        }
    }

    if (-not $programFolder) {
        Write-Host "Внимание: Папка с программой '$installFolder' не найдена" -ForegroundColor Yellow
        return
    }

    Write-Host "Папка программы найдена: $($programFolder.FullName)" -ForegroundColor Green

    # --- Поиск утилиты индексации ---
    $exePath     = Join-Path $programFolder.FullName "Client" | Join-Path -ChildPath $exeToRun
    $exePathRoot = Join-Path $programFolder.FullName $exeToRun

    $finalExe = $null
    if (Test-Path $exePath) {
        $finalExe = $exePath
    } elseif (Test-Path $exePathRoot) {
        $finalExe = $exePathRoot
    }

    if (-not $finalExe) {
        Write-Host "Внимание: Утилита $exeToRun не найдена" -ForegroundColor Red
        return
    }

    Write-Host "Запуск утилиты: $finalExe" -ForegroundColor Cyan
    try {
        $utilityProcess = Start-Process -FilePath $finalExe -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop
        Write-Host "Утилита завершила работу (ExitCode: $($utilityProcess.ExitCode))" -ForegroundColor Green
    }
    catch {
        Write-Host "ОШИБКА запуска утилиты: $($_.Exception.Message)" -ForegroundColor Red
    }
}

# --- Обработка одной программы ---
function Process-Program {
    param(
        [string]$folderName,
        [string]$programName,
        [string]$installFolder,
        [string]$sourceFolder
    )

    Write-Host ""
    Write-Host "=====================================================" -ForegroundColor Magenta
    Write-Host ">>> Программа: $programName (папка $folderName)" -ForegroundColor Magenta
    Write-Host "=====================================================" -ForegroundColor Magenta

    # --- 1. Проверяем папку-источник ---
    if (-not (Test-Path $sourceFolder)) {
        Write-Host "Папка-источник не найдена: $sourceFolder" -ForegroundColor Red
        return $false
    }

    # --- 2. Ищем .rar в папке-источнике ---
    $rarFiles = Get-ChildItem -Path $sourceFolder -Filter "*.rar" -File -Recurse -ErrorAction SilentlyContinue
    if ($rarFiles.Count -eq 0) {
        Write-Host "В папке $folderName не найдено .rar архивов" -ForegroundColor Red
        return $false
    }

    $rarToUse = $rarFiles | Select-Object -First 1
    Write-Host "Найден архив: $($rarToUse.Name)" -ForegroundColor Green

    # --- 3. Чистим рабочую папку от предыдущих распаковок ---
    Clear-WorkFolder -FolderPath $workBase

    # --- 4. Копируем .rar из сетевой папки в рабочую (локально) ---
    $localRarPath = Join-Path $workBase $rarToUse.Name
    Write-Host "Копирование архива: $($rarToUse.FullName) -> $localRarPath" -ForegroundColor Cyan

    try {
        Copy-Item -Path $rarToUse.FullName -Destination $localRarPath -Force -ErrorAction Stop
        $sizeMb = [math]::Round((Get-Item $localRarPath).Length / 1MB, 2)
        Write-Host "Архив скопирован локально ($sizeMb MB)" -ForegroundColor Green
    }
    catch {
        Write-Host "ОШИБКА копирования архива: $($_.Exception.Message)" -ForegroundColor Red
        return $false
    }

    # --- 5. Распаковываем ЛОКАЛЬНУЮ копию ---
    if (-not (Extract-RarArchive -archivePath $localRarPath -destinationPath $workBase)) {
        Write-Host "Распаковка не удалась, пропускаем $programName" -ForegroundColor Red
        return $false
    }

    # --- 6. Ищем .msi в распакованном ---
    $msiFile = Get-ChildItem -Path $workBase -Filter "*.msi" -File -Recurse -ErrorAction SilentlyContinue |
        Select-Object -First 1

    if (-not $msiFile) {
        Write-Host "В распакованном архиве не найден .msi" -ForegroundColor Red
        return $false
    }

    $msiPath = $msiFile.FullName
    Write-Host "Найден установщик: $($msiFile.Name)" -ForegroundColor Green
    Write-Host "Путь: $msiPath" -ForegroundColor Gray

    # --- 7. Удаляем старую версию ---
    $existingPackage = Find-InstalledProgram -exactName $programName
    if ($existingPackage) {
        Write-Host "Программа найдена. Удаляем..." -ForegroundColor Yellow
        Uninstall-Program -displayName $existingPackage.Name -package $existingPackage
    } else {
        Write-Host "Программа не найдена. Выполняется установка..." -ForegroundColor Green
    }

    # --- 8. Установка MSI + убийство процесса индексации + запуск утилиты ---
    Install-Program -msiPath $msiPath -programName $programName -installFolder $installFolder

    # --- 9. Чистим рабочую папку (удаляем распакованное и локальный .rar) ---
    Clear-WorkFolder -FolderPath $workBase

    # --- 10. Чистим папку-источник (кроме .txt — там маркер версии) ---
    Clear-FolderExceptTxt -FolderPath $sourceFolder

    Write-Host "Программа '$programName' успешно установлена!" -ForegroundColor Green
    Write-Host "---------------------------------------------------" -ForegroundColor Gray
    return $true
}

Write-Host ""
Write-Host "=====================================================" -ForegroundColor Cyan
Write-Host "НАЧАЛО ОБРАБОТКИ ПАПОК" -ForegroundColor Cyan
Write-Host "=====================================================" -ForegroundColor Cyan

$successCount = 0
$totalCount   = $programs.Count

foreach ($program in $programs) {
    $folderName    = $program.Folder
    $programName   = $program.Name
    $installFolder = $program.InstallFolder
    $sourceFolder  = Join-Path -Path $rootFolder -ChildPath $folderName

    if (Process-Program -folderName $folderName -programName $programName -installFolder $installFolder -sourceFolder $sourceFolder) {
        $successCount++
    }
}

Write-Host ""
Write-Host "=====================================================" -ForegroundColor Green
Write-Host "ОБРАБОТКА ВСЕХ ПАПОК ЗАВЕРШЕНА" -ForegroundColor Green
Write-Host "Успешно: $successCount из $totalCount" -ForegroundColor Green
Write-Host "=====================================================" -ForegroundColor Green

Read-Host "123"
#exit 0

Конец downloader.ps1



Начало watcher.ps1

# --- 1. Проверка и запрос прав администратора ---
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Host "Требуются права администратора. Запуск от имени администратора..." -ForegroundColor Yellow
    Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
    exit
}

Write-Host "=== WATCHER: наблюдение за success.flag ===" -ForegroundColor Cyan
Write-Host "Запущено от имени администратора" -ForegroundColor Green
Write-Host ""

# --- 2. Пути ---
# Папка, где создаётся success.flag (должна совпадать с FTP-скриптом)
$watcherPath = "D:\win10\Share\App"

# Файл-флаг
$flagFile = Join-Path $watcherPath "success.flag"

# Lock-файл — защита от двойной обработки
$lockFile = Join-Path $watcherPath "watcher.processing.lock"

# Порог "старого" флага (в часах) — если старше, удаляем без обработки
$staleFlagHours = 24

# --- 3. Путь к downloader.ps1: ищем рядом с watcher.ps1 ---
$scriptDir = $PSScriptRoot
if (-not $scriptDir) {
    $scriptDir = Split-Path -Parent $PSCommandPath
}
if (-not $scriptDir) {
    $scriptDir = Get-Location
}

$scriptPath = Join-Path $scriptDir "downloader.ps1"

Write-Host "Папка watcher'а: $scriptDir" -ForegroundColor Cyan
Write-Host "Целевой скрипт:  $scriptPath" -ForegroundColor Cyan
Write-Host "Отслеживаемая папка: $watcherPath" -ForegroundColor Cyan
Write-Host "Файл-флаг:       $flagFile" -ForegroundColor Cyan
Write-Host ""

# --- 4. Проверка существования путей ---
if (-not (Test-Path $watcherPath)) {
    Write-Host "ОШИБКА: папка наблюдения не существует: $watcherPath" -ForegroundColor Red
    Write-Host "Проверьте путь и права доступа." -ForegroundColor Red
    Read-Host "Нажмите Enter для выхода"
    exit 1
}

if (-not (Test-Path $scriptPath)) {
    Write-Host "ОШИБКА: downloader.ps1 не найден: $scriptPath" -ForegroundColor Red
    Write-Host "Проверьте, что downloader.ps1 лежит рядом с watcher.ps1." -ForegroundColor Red
    Read-Host "Нажмите Enter для выхода"
    exit 1
}

function Invoke-FlagProcessing {
    param([string]$FlagPath)

    Write-Host ""
    Write-Host "========================================" -ForegroundColor Cyan
    Write-Host "СИГНАЛ ПОЛУЧЕН!" -ForegroundColor Green
    Write-Host "Файл: $FlagPath" -ForegroundColor Yellow
    Write-Host "Время: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
    Write-Host "========================================" -ForegroundColor Cyan

    # --- Проверка lock-файла (защита от двойной обработки) ---
    if (Test-Path $lockFile) {
        Write-Host "Обработка уже идёт (lock-файл существует). Пропускаем." -ForegroundColor Yellow
        Write-Host "Lock-файл: $lockFile" -ForegroundColor Gray
        Write-Host "========================================" -ForegroundColor Cyan
        Write-Host ""
        return
    }

    # --- Ставим lock ---
    try {
        New-Item -ItemType File -Path $lockFile -Force -ErrorAction Stop | Out-Null
        Write-Host "Lock-файл создан: $lockFile" -ForegroundColor Gray
    }
    catch {
        Write-Host "ОШИБКА создания lock-файла: $($_.Exception.Message)" -ForegroundColor Red
        Write-Host "========================================" -ForegroundColor Cyan
        Write-Host ""
        return
    }

    try {
        # --- Небольшая задержка, чтобы файл гарантированно дописался ---
        Start-Sleep -Milliseconds 500

        if (-not (Test-Path $FlagPath)) {
            Write-Host "ВНИМАНИЕ: файл-флаг исчез до начала обработки" -ForegroundColor Red
            return
        }

        # --- Показываем содержимое ---
        try {
            $content = Get-Content $FlagPath -Raw -ErrorAction Stop
            Write-Host "Содержимое файла:" -ForegroundColor Gray
            Write-Host $content -ForegroundColor Gray
        } catch {
            Write-Host "Не удалось прочитать содержимое: $($_.Exception.Message)" -ForegroundColor Red
        }

        # --- Запуск downloader.ps1 в отдельном окне ---
        Write-Host ""
        Write-Host "Запуск downloader.ps1 в отдельном окне: $scriptPath" -ForegroundColor Cyan

        $exitCode = -1
        try {
            $proc = Start-Process powershell.exe -ArgumentList @(
                "-NoProfile",
                "-ExecutionPolicy", "Bypass",
                "-File", "`"$scriptPath`""
            ) -PassThru -Wait -ErrorAction Stop

            $exitCode = $proc.ExitCode
            Write-Host "downloader.ps1 завершён с кодом: $exitCode" -ForegroundColor $(if ($exitCode -eq 0) { "Green" } else { "Red" })
        }
        catch {
            Write-Host "ОШИБКА запуска downloader.ps1: $($_.Exception.Message)" -ForegroundColor Red
            $exitCode = -1
        }

        # --- Удаляем флаг только при успехе ---
        if ($exitCode -eq 0) {
            try {
                Remove-Item $FlagPath -Force -ErrorAction Stop
                Write-Host "Обработка успешна, файл-флаг удалён" -ForegroundColor Green
            }
            catch {
                Write-Host "Не удалось удалить файл-флаг: $($_.Exception.Message)" -ForegroundColor Red
            }
        }
        else {
            Write-Host "downloader.ps1 завершился с кодом $exitCode — файл-флаг оставлен для повторной попытки" -ForegroundColor Red
        }
    }
    finally {
        # --- Снимаем lock в любом случае ---
        Remove-Item $lockFile -Force -ErrorAction SilentlyContinue
        Write-Host "Lock-файл снят" -ForegroundColor Gray
        Write-Host "========================================" -ForegroundColor Cyan
        Write-Host ""
    }
}

if (Test-Path $flagFile) {
    $flagInfo = Get-Item $flagFile
    $ageHours = ((Get-Date) - $flagInfo.CreationTime).TotalHours

    Write-Host "ВНИМАНИЕ: success.flag уже существует при старте!" -ForegroundColor Yellow
    Write-Host "Создан: $($flagInfo.CreationTime.ToString('yyyy-MM-dd HH:mm:ss'))" -ForegroundColor Yellow
    Write-Host "Возраст: $([math]::Round($ageHours, 1)) ч" -ForegroundColor Yellow

    if ($ageHours -gt $staleFlagHours) {
        Write-Host "Флаг старше $staleFlagHours ч — удаляю как устаревший." -ForegroundColor Yellow
        Remove-Item $flagFile -Force -ErrorAction SilentlyContinue
    }
    else {
        Write-Host "Обрабатываю существующий success.flag немедленно..." -ForegroundColor Cyan
        Invoke-FlagProcessing -FlagPath $flagFile
    }
    Write-Host ""
}
else {
    Write-Host "success.flag отсутствует. Ждём появления..." -ForegroundColor Green
    Write-Host ""
}

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $watcherPath
$watcher.Filter = "success.flag"
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::LastWrite
$watcher.EnableRaisingEvents = $true
$watcher.IncludeSubdirectories = $false

# --- Действие при создании файла ---
$action = {
    $path = $Event.SourceEventArgs.FullPath
    Invoke-FlagProcessing -FlagPath $path
}

# --- Регистрируем событие ---
$eventJob = Register-ObjectEvent -InputObject $watcher -EventName "Created" -Action $action

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Наблюдатель запущен!" -ForegroundColor Green
Write-Host "Отслеживается папка: $watcherPath" -ForegroundColor Yellow
Write-Host "Ожидание файла: success.flag" -ForegroundColor Yellow
Write-Host ""
Write-Host "Для остановки нажмите Ctrl+C" -ForegroundColor Red
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""

# --- Держим скрипт запущенным ---
try {
    while ($true) {
        Start-Sleep -Seconds 1
    }
}
finally {
    Write-Host ""
    Write-Host "Остановка watcher'а..." -ForegroundColor Yellow

    Unregister-Event -SubscriptionId $eventJob.Id -ErrorAction SilentlyContinue
    $watcher.Dispose()

    # Снимаем lock, если он остался от прерванной обработки
    Remove-Item $lockFile -Force -ErrorAction SilentlyContinue

    Write-Host "Наблюдатель остановлен." -ForegroundColor Red
}

Конец watcher.ps1