# Tablo2SQL-TR başlatıcı — Windows (PowerShell 5.1+) # baslat.bat tarafından çağrılır: baslat.bat [--kontrol | --kisayol | --sifirla | --port N | --tarayici-yok] $ErrorActionPreference = 'Continue' try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 } catch {} $OutputEncoding = [System.Text.Encoding]::UTF8 [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 $Root = Split-Path -Parent $PSScriptRoot Set-Location $Root $MinMinor = 10 $Wanted = '3.12' $PyFull = '3.12.10' $Venv = Join-Path $Root '.venv' $VPy = Join-Path $Venv 'Scripts\python.exe' function Ok($m) { Write-Host ' [TAMAM] ' -ForegroundColor Green -NoNewline; Write-Host $m } function Warn($m) { Write-Host ' [UYARI] ' -ForegroundColor Yellow -NoNewline; Write-Host $m } function Err($m) { Write-Host ' [HATA] ' -ForegroundColor Red -NoNewline; Write-Host $m } function Info($m) { Write-Host ' [BİLGİ] ' -ForegroundColor Cyan -NoNewline; Write-Host $m } function Ask($q) { $a = Read-Host " $q [E/h]" return ([string]::IsNullOrWhiteSpace($a) -or $a.Trim().ToLower().StartsWith('e') -or $a.Trim().ToLower().StartsWith('y')) } function Fail($code = 1) { Write-Host '' Read-Host ' Bir sorun oluştu. Pencereyi kapatmak için Enter''a basın' | Out-Null exit $code } Write-Host '' Write-Host ' ═══ Tablo2SQL-TR başlatıcı (Windows) ═══' -ForegroundColor Blue $Reset = $false $PassArgs = @() foreach ($a in $args) { if ($a -eq '--sifirla') { $Reset = $true } else { $PassArgs += $a } } # ======================================================================= Python bul function Test-Py([string]$exe) { if (-not $exe) { return $null } # Microsoft Store kısayolu (WindowsApps\python.exe) gerçek Python değildir: Store'u açar if ($exe -like '*\WindowsApps\*') { return $null } try { $v = & $exe -c "import sys; print('%d.%d|%s' % (sys.version_info[0], sys.version_info[1], sys.executable))" 2>$null if ($LASTEXITCODE -ne 0 -or -not $v) { return $null } $parts = $v.Trim().Split('|') $mm = $parts[0].Split('.') if ([int]$mm[0] -eq 3 -and [int]$mm[1] -ge $MinMinor) { return $parts[1] } } catch {} return $null } function Find-Python { # 1) py başlatıcısı (python.org kurulumuyla gelir) if (Get-Command py -ErrorAction SilentlyContinue) { foreach ($ver in @('3.13', '3.12', '3.11', '3.10')) { try { $p = & py "-$ver" -c "import sys; print(sys.executable)" 2>$null if ($LASTEXITCODE -eq 0 -and $p) { $r = Test-Py $p.Trim(); if ($r) { return $r } } } catch {} } } # 2) PATH üzerindeki python / python3 foreach ($n in @('python', 'python3')) { foreach ($c in @(Get-Command $n -All -ErrorAction SilentlyContinue)) { $r = Test-Py $c.Source; if ($r) { return $r } } } # 3) Bilinen kurulum klasörleri (PATH henüz yenilenmemiş olabilir) $dirs = @("$env:LOCALAPPDATA\Programs\Python", "$env:ProgramFiles\Python*", "$env:ProgramFiles", "${env:ProgramFiles(x86)}") foreach ($d in $dirs) { foreach ($exe in @(Get-ChildItem -Path $d -Filter python.exe -Recurse -Depth 2 -ErrorAction SilentlyContinue | Where-Object { $_.FullName -match 'Python3\d+' } | Sort-Object FullName -Descending)) { $r = Test-Py $exe.FullName; if ($r) { return $r } } } # 4) uv ile kurulmuş Python $uv = Get-Command uv -ErrorAction SilentlyContinue if ($uv) { try { $p = & uv python find $Wanted 2>$null; $r = Test-Py $p; if ($r) { return $r } } catch {} } return $null } function Install-Python { Warn "Python 3.$MinMinor veya daha yenisi bulunamadı." if (Get-Command winget -ErrorAction SilentlyContinue) { if (Ask "winget ile Python $Wanted kurulsun mu? (yönetici izni gerekmez)") { winget install -e --id "Python.Python.$Wanted" --scope user --silent --accept-package-agreements --accept-source-agreements if ($LASTEXITCODE -eq 0 -or (Find-Python)) { return $true } Warn 'winget kurulumu başarısız oldu; resmi kurulum dosyası denenecek.' } } if (Ask "Python $PyFull resmi kurulum dosyası python.org'dan indirilip sessizce kurulsun mu?") { $arch = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { 'arm64' } elseif ([Environment]::Is64BitOperatingSystem) { 'amd64' } else { '' } $file = if ($arch) { "python-$PyFull-$arch.exe" } else { "python-$PyFull.exe" } $url = "https://www.python.org/ftp/python/$PyFull/$file" $dst = Join-Path $env:TEMP $file Info "İndiriliyor: $url" try { $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri $url -OutFile $dst -UseBasicParsing } catch { Err "İndirme başarısız: $($_.Exception.Message)"; return $false } Info 'Kuruluyor (kullanıcı hesabına, PATH ve py başlatıcısıyla)…' $p = Start-Process -FilePath $dst -ArgumentList '/quiet', 'InstallAllUsers=0', 'PrependPath=1', 'Include_launcher=1', 'Include_test=0' -Wait -PassThru if ($p.ExitCode -eq 0) { return $true } Err "Kurulum dosyası $($p.ExitCode) koduyla bitti." } Err 'Python kurulmadı. Elle kurulum:' Write-Host " 1. https://www.python.org/downloads/windows/ adresinden Python $Wanted indirin" Write-Host ' 2. Kurulumun ilk ekranında "Add python.exe to PATH" kutusunu işaretleyin' Write-Host ' 3. Bu başlatıcıyı yeniden çalıştırın' try { Start-Process 'https://www.python.org/downloads/windows/' } catch {} return $false } # ======================================================================= ana akış Write-Host '' Write-Host '0) Ön koşullar' -ForegroundColor White $Py = Find-Python if (-not $Py) { if (-not (Install-Python)) { Fail } # yeni kurulan Python'un PATH'ini bu oturuma al $env:Path = [Environment]::GetEnvironmentVariable('Path', 'User') + ';' + [Environment]::GetEnvironmentVariable('Path', 'Machine') $Py = Find-Python if (-not $Py) { Err 'Kurulumdan sonra Python bulunamadı; pencereyi kapatıp başlatıcıyı yeniden çalıştırın.'; Fail } } $PyVer = & $Py -c "import platform; print(platform.python_version())" Ok "Python: $Py ($PyVer)" if ($PassArgs.Count -gt 0 -and $PassArgs[0] -eq '--kisayol') { & $Py (Join-Path $Root 'scripts\kisayol.py') if ($LASTEXITCODE -ne 0) { Fail } else { Read-Host ' Tamam. Kapatmak için Enter' | Out-Null; exit 0 } } # ---- sanal ortam if ($Reset -and (Test-Path $Venv)) { Info 'Sanal ortam siliniyor…'; Remove-Item -Recurse -Force $Venv } if ((Test-Path $Venv) -and -not (Test-Py $VPy)) { Warn 'Mevcut .venv bozuk (klasör taşınmış veya Python güncellenmiş olabilir); yeniden oluşturuluyor.' Remove-Item -Recurse -Force $Venv } if (-not (Test-Path $Venv)) { Info 'Sanal ortam oluşturuluyor (.venv)…' & $Py -m venv $Venv if ($LASTEXITCODE -ne 0 -or -not (Test-Path $VPy)) { Err 'Sanal ortam oluşturulamadı. Klasörün yazılabilir olduğundan emin olun (ör. Program Files dışında bir yere çıkarın).' Fail } Ok 'Sanal ortam hazır.' } else { Ok 'Sanal ortam mevcut.' } # ---- paketler (requirements.txt değiştiyse yeniden kur) $HashFile = Join-Path $Venv '.req_hash' $NewHash = (Get-FileHash -Algorithm SHA256 (Join-Path $Root 'requirements.txt')).Hash.ToLower() $OldHash = if (Test-Path $HashFile) { (Get-Content $HashFile -Raw).Trim() } else { '' } if ($OldHash -ne $NewHash) { Info 'Python paketleri kuruluyor (ilk kurulum birkaç dakika sürebilir)…' & $VPy -m pip install --disable-pip-version-check -q --upgrade pip 2>$null | Out-Null & $VPy -m pip install --disable-pip-version-check -r (Join-Path $Root 'requirements.txt') if ($LASTEXITCODE -ne 0) { Err 'Paket kurulumu başarısız. İnternet bağlantısını kontrol edin; sorun sürerse: baslat.bat --sifirla' Fail } Set-Content -Path $HashFile -Value $NewHash -Encoding ASCII Ok 'Paketler kuruldu.' } # ---- ortak başlatıcı & $VPy (Join-Path $Root 'scripts\baslat.py') @PassArgs if ($LASTEXITCODE -ne 0) { Fail $LASTEXITCODE }