import { app } from 'electron' import { join } from 'path' import { is } from '@electron-toolkit/utils' /** * Resolves the directory holding the bundled binaries (yt-dlp.exe, ffmpeg.exe). * * In dev they live in the repo at resources/bin/. * In a packaged build, electron-builder's extraResources copies them to * /bin (see electron-builder.yml), reachable via process.resourcesPath. */ export function getBinDir(): string { return is.dev ? join(app.getAppPath(), 'resources', 'bin') : join(process.resourcesPath, 'bin') } export function getYtdlpPath(): string { return join(getBinDir(), 'yt-dlp.exe') } export function getFfmpegPath(): string { return join(getBinDir(), 'ffmpeg.exe') } /** * yt-dlp finds ffprobe via --ffmpeg-location (the bin dir), so the app never * spawns it directly — but it must be present, or duration-aware post-processing * (SponsorBlock-remove, --force-keyframes-at-cuts, --split-chapters) fails. This * accessor exists so startDownload can assert its presence up front. */ export function getFfprobePath(): string { return join(getBinDir(), 'ffprobe.exe') } /** Optional bundled external downloader; absent unless dropped into resources/bin. */ export function getAria2cPath(): string { return join(getBinDir(), 'aria2c.exe') } /** * Absolute path to a Windows system executable (e.g. taskkill.exe, schtasks.exe). * * SECURITY (audit F3): system tools are resolved by full path under System32 * rather than by bare name, so a same-named binary planted in the current * working directory or earlier on PATH can't be invoked in their place — a real * risk for the portable build, which runs from user-writable locations. */ export function getSystem32Path(exe: string): string { return join(process.env.SystemRoot || 'C:\\Windows', 'System32', exe) }