Skip to content

Commit c8eb2d6

Browse files
committed
feat: smartly open and select downloaded files in any file manager (Windows only)
1 parent 5f89c48 commit c8eb2d6

1 file changed

Lines changed: 78 additions & 5 deletions

File tree

powershell/yt-download.ps1

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,57 @@ if ($url -and -not $install -and -not $uninstall) {
625625
}
626626
}
627627

628+
<#*==========================================================================
629+
* ℹ Handle select downloaded file in Windows
630+
===========================================================================#>
631+
if ($IsWindows) {
632+
# Définition de l'API Windows native via C#
633+
$Win32Signature = @'
634+
[DllImport("shell32.dll", ExactSpelling = true)]
635+
public static extern int SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string pszName, IntPtr pbc, out IntPtr ppidl, uint sfgaoIn, out uint psfgaoOut);
636+
637+
[DllImport("shell32.dll", ExactSpelling = true)]
638+
public static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, IntPtr[] apidl, uint dwFlags);
639+
640+
[DllImport("ole32.dll", ExactSpelling = true)]
641+
public static extern void CoTaskMemFree(IntPtr pv);
642+
'@
643+
644+
$ShUtils = Add-Type -MemberDefinition $Win32Signature -Name "ShellUtils" -Namespace "Win32API" -PassThru
645+
646+
function Show-InFileManager {
647+
param (
648+
[string]$FilePath
649+
)
650+
651+
$AbsolutePath = (Resolve-Path -Path $FilePath -ErrorAction Stop).Path
652+
653+
# 1. Obtenir le PIDL (Pointer to an Item ID List) du fichier ciblé
654+
$Pidl = [IntPtr]::Zero
655+
$SfgaoOut = 0
656+
$Result = $ShUtils::SHParseDisplayName($AbsolutePath, [IntPtr]::Zero, [ref]$Pidl, 0, [ref]$SfgaoOut)
657+
658+
if ($Result -eq 0 -and $Pidl -ne [IntPtr]::Zero) {
659+
try {
660+
# 2. Appeler l'API native.
661+
# En passant le PIDL du fichier en premier argument et 0 en nombre d'éléments enfants,
662+
# Windows (ou DOpus via interception) ouvre le dossier parent et sélectionne le fichier.
663+
[void]$ShUtils::SHOpenFolderAndSelectItems($Pidl, 0, $null, 0)
664+
}
665+
finally {
666+
# 3. Libérer la mémoire managée requise par l'API COM/Shell
667+
if ($Pidl -ne [IntPtr]::Zero) {
668+
$ShUtils::CoTaskMemFree($Pidl)
669+
}
670+
}
671+
}
672+
else {
673+
# Sécurité si l'API échoue : retour à la méthode basique
674+
Start-Process explorer.exe -ArgumentList "/select,`"$AbsolutePath`""
675+
}
676+
}
677+
}
678+
628679
<#*==========================================================================
629680
* ℹ BUILD COMMAND TO RUN
630681
===========================================================================#>
@@ -649,10 +700,6 @@ if ($url -and -not $install -and -not $uninstall) {
649700
$options += @("--replace-in-metadata", "title", '\|', "-")
650701
}
651702

652-
if ($SelectDownloadedFile -and -not $IsTest) {
653-
$options += @("--exec", 'pwsh -NoProfile -NonInteractive -Command "Start-Process explorer.exe -ArgumentList \"/select,`\"{}`\"\""')
654-
}
655-
656703
if ($IsTest) {
657704
# quote option value when it contains space
658705
$optionsString = ($script:options | ForEach-Object {
@@ -711,6 +758,16 @@ if ($url -and -not $install -and -not $uninstall) {
711758
$optionsString = $optionsString -replace $pattern, $substitution -replace ',\s+', ','
712759
}
713760

761+
if ($SelectDownloadedFile -and -not $IsTest -and $IsWindows) {
762+
# 1. Generate a unique temporary file path
763+
$TempPathFile = [System.IO.Path]::GetTempFileName()
764+
765+
# 2. We use --exec to write the downloaded file path to our temporary file
766+
$options += @(
767+
"--exec", "pwsh -NoProfile -NonInteractive -Command `"Out-File -FilePath '$TempPathFile' -InputObject '{}' -Encoding utf8`""
768+
)
769+
}
770+
714771
if ($debug) {
715772
Write-Host "`$options: $options`n" -ForegroundColor Cyan
716773
Write-Host "`$optionsString: $optionsString`n" -ForegroundColor Yellow
@@ -732,7 +789,23 @@ if ($url -and -not $install -and -not $uninstall) {
732789
if ($LASTEXITCODE -eq 0) {
733790

734791
if (-not $IsTest) {
735-
Write-Host "`nOPEN OUTPUT DIRECTORY" -ForegroundColor Cyan
792+
793+
if ($IsWindows -and $SelectDownloadedFile) {
794+
795+
Write-Host "`nOPEN OUTPUT DIRECTORY" -ForegroundColor Cyan
796+
797+
# Retrieve downloaded file path after execution
798+
if (Test-Path $TempPathFile) {
799+
$DownloadedFilePath = (Get-Content -Path $TempPathFile -Raw).Trim()
800+
Remove-Item -Path $TempPathFile -ErrorAction SilentlyContinue
801+
Write-Host "DownloadedFilePath : `"$DownloadedFilePath`"" -ForegroundColor Yellow
802+
}
803+
804+
# Apply file selection logic
805+
if ($DownloadedFilePath) {
806+
Show-InFileManager -FilePath $DownloadedFilePath
807+
}
808+
}
736809
}
737810

738811
# Play a beep to notify

0 commit comments

Comments
 (0)