La sección "Variables" dentro del script permite configurar varias cosas, entre ellas:
- Los tamaños de diccionario.
- Las extensiones de archivo que se deben procesar sin aplicar compresión.
- Preservar solamente el archivo RAR generado con el menor tamaño de todos. (eliminar los archivos RAR de mayor tamaño)
- Especificar una diferencia de tamaño (tolerancia) arbitraria para eliminar archivos RAR generados (con mayores tamaños de diccionario) de un tamaño de archivo similar.
- Enviar los archivos RAR eliminados a la papelera de reciclaje.
Es muy útil, por ejemplo, para comprimir de forma automatizada archivos ISO de consolas, y obtener así el mejor resultado entre Tamaño de diccionario / Tamaño de archivo.
Código
<# =========================================================================================== | | | Variables | | | =========================================================================================== #> $rarExecutablePath = "C:\Program Files\WinRAR\rar.exe" $dictionarySizes = @(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048) $toleranceSizeDiff = "1MB" $keepOnlySmallestRarFile = $true $sendRarFilesToRecycleBin = $false $compressedFileTypesArchive = @( "7z" , "arc", "bz2" , "bzip", "bzip2", "gz" , "gz2", "gza" , "gzi" , "gzip" , "lha", "lz" , "lz4" , "lzh" , "lzma" , "rar", "sfx", "tgz" , "tlz" , "tlzma", "uha", "zip", "zipx", "zpaq" ) $compressedFileTypesAudio = @( "aac", "ac3", "fla","flac", "m4a", "mp3", "ogg", "ogm", "usm", "wma" ) $compressedFileTypesVideo = @( "asf", "avc", "avi" , "bik" , "bk2" , "f4v" , "flv" , "m1v", "m2t", "m2ts", "m2v" , "m4v" , "mpv4", "mkv", "mov", "mp4" , "mpeg", "mpg" , "mts" , "qt" , "ts" , "vob" , "vp6" , "webm", "wmv" ) $compressedFileTypesOther = @( "avif", "jpeg", "jpg" , "gif" , "pdf", "pam" , "paq6", "paq7", "paq8", "par" , "par2", "wad" ) [string]$fileTypesToKeepUncompressed = ( $compressedFileTypesArchive + $compressedFileTypesAudio + $compressedFileTypesVideo + $compressedFileTypesOther ) -join ';' <# =========================================================================================== | | | rar.exe commands (only those used in this script) | | | =========================================================================================== <Commands> a Add files to archive <Switches> -am[s,r] Archive name and time [save, restore] -c- Disable comments show -cfg- Ignore configuration file and RAR environment variable. -dh Open shared files -ep1 Exclude base directory from names -ht[b|c] Select hash type [BLAKE2,CRC32] for file checksum -id[c,d,n,p,q] Display or disable messages -ilog[name] Log errors to file -isnd[-] Control notification sounds -m<0..5> Set compression level (0-store...3-default...5-maximal) -ma[4|5] Specify a version of archiving format -md<n>[k,m,g] Dictionary size in KB, MB or GB -ms[list] Specify file types to store. -o[+|-] Set the overwrite mode -oc Set NTFS Compressed attribute. -oh Save hard links as the link instead of the file -oi[0-4][:min] Save identical files as references -ol[a] Process symbolic links as the link [absolute paths] -oni Allow potentially incompatible names -qo[-|+] Add quick open information [none|force] -r Recurse subdirectories -ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms -s- Disable solid archiving -t Test files after archiving -tk Keep original archive time -tl Set archive time to newest file -ts[m,c,a,p] Save or restore time (modification, creation, access, preserve) -u Update files -w<path> Assign work directory #> <# =========================================================================================== | | | .NET Code | | | =========================================================================================== #> Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class Win32Functions { [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)] public static extern long StrFormatByteSizeW(long fileSize, System.Text.StringBuilder buffer, int bufferSize); } "@ <# =========================================================================================== | | | Functions | | | =========================================================================================== #> function Show-WelcomeScreen { Clear-Host Write-Host "" Write-Host " $($host.ui.RawUI.WindowTitle)" Write-Host " +========================================================+" Write-Host " | |" Write-Host " | This script will use RAR.exe to compress each file in |" Write-Host " | the current working directory individually, each using |" Write-Host " | different dictionary sizes, with max. compression, |" Write-Host " | generating this way multiple RAR files for evaluating |" Write-Host " | compression rates on these dictionary sizes. |" Write-Host " | |" Write-Host " +=========================================================+" Write-Host "" Write-Host " Script Settings " -ForegroundColor DarkGray Write-Host " ===========================" -ForegroundColor DarkGray Write-Host " RAR Executable Path: $([System.IO.Path]::GetFullPath($rarExecutablePath))" -ForegroundColor Gray Write-Host "" -ForegroundColor DarkGray Write-Host " Dictionary Sizes (Megabyte): $($dictionarySizes -join ', ')" -ForegroundColor Gray Write-Host " The script will create a RAR archive for each specified dictionary size." -ForegroundColor DarkGray Write-Host "" -ForegroundColor DarkGray Write-Host " File Types To Keep Uncompressed: `$keepCompressedFileTypesUncompressed" -ForegroundColor Gray Write-Host " The script will instruct RAR to don't compress the specified known compressed file types." -ForegroundColor DarkGray Write-Host " (See `$keepCompressedFileTypesUncompressed variable definition to manage the file types)" -ForegroundColor DarkGray Write-Host "" -ForegroundColor DarkGray Write-Host " Tolerance File Size Difference: $toleranceSizeDiff" -ForegroundColor Gray Write-Host " Any newly created RAR file whose file size compared to previously " -ForegroundColor DarkGray Write-Host " created RAR files is within the specified tolerance value, it will be deleted." -ForegroundColor DarkGray Write-Host " For example, if `$toleranceSizeDiff value is 1MB:" -ForegroundColor DarkGray Write-Host " If a created RAR file of 32 MB dict. size has a file size of 100 MB," -ForegroundColor DarkGray Write-Host " and then a newly created RAR file of 64 MB dict. size has a file size of 99 MB, " -ForegroundColor DarkGray Write-Host " the RAR file of 64 MB dict. size will be deleted because it only differs in 1MB or less." -ForegroundColor DarkGray Write-Host "" -ForegroundColor DarkGray Write-Host " Keep only smallest rar file: $keepOnlySmallestRarFile" -ForegroundColor Gray Write-Host " If True, the script will delete any newly created RAR file " -ForegroundColor DarkGray Write-Host " whose file size is bigger than previously created RAR files." -ForegroundColor DarkGray Write-Host " Note: it takes into account the specified `$toleranceSizeDiff value." -ForegroundColor DarkGray Write-Host "" -ForegroundColor DarkGray Write-Host " Send RAR files to recycle bin: $sendRarFilesToRecycleBin" -ForegroundColor Gray Write-Host " If True, the script will send RAR files to recycle bin instead of permanently deleting them." -ForegroundColor DarkGray Write-Host "" } function Confirm-Continue { Write-Host " Press 'Y' key to continue or 'N' to exit." Write-Host "" Write-Host " -Continue? (Y/N)" do { $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $char = $key.Character.ToString().ToUpper() if ($char -ne "Y" -and $char -ne "N") { [console]::beep(1500, 500) } } while ($char -ne "Y" -and $char -ne "N") if ($char -eq "N") {Exit(1)} else {Clear-Host} } function Compress-Files { Add-Type -AssemblyName Microsoft.VisualBasic $dictionarySizes = $dictionarySizes | Sort-Object # Partir y formatear la cadena de file types para acomodarlo a la linea de argumentos de rar.exe if (-not [String]::IsNullOrEmpty($fileTypesToKeepUncompressed)) { $fileTypeTokens = $fileTypesToKeepUncompressed -split ';' $fileTypesArgumentLines = @() for ($i = 0; $i -lt $fileTypeTokens.Count; $i += 20) { $fileTypesArgumentLines += "-ms" + ($fileTypeTokens[$i..($i + 19)] -join ';') + [Environment]::NewLine } if ($fileTypesArgumentLines.Count -gt 0) { $fileTypesArgumentLines[-1] = $fileTypesArgumentLines[-1] -replace [Environment]::NewLine, '' } } else { $fileTypesArgumentLines = "-ms " } foreach ($inputFile in Get-ChildItem -LiteralPath "$PSScriptRoot" -File) { if ($inputFile.Name -eq [System.IO.Path]::GetFileName($PSCommandPath)) { continue } # Keeps track of created rar files by rar.exe $createdRarFiles = New-Object System.Collections.Generic.List[System.IO.FileInfo] foreach ($size in $dictionarySizes) { if (($size -ne $dictionarySizes[0]) -and ($inputFile.Length * 4) -le ($size * 1MB)) { $formattedSize = Format-FileSize -fileSize $inputFile.Length Write-Host "Ignoring compression with too big dictionary size of $size mb for a $formattedSize file: `"$($inputFile.Name)`"..." -ForegroundColor Yellow continue } $outputRarFilePath = "$($inputFile.FullName)_$($size)mb.rar" $errorLogFilePath = "$($inputFile.FullName)_$($size)mb_error.log" $arguments = @( " a -u -ams -c- -cfg- -dh -ep1 -htb -idcdn -isnd- -iver -m5 -ma5 -md$($size)m", " -o+ -oc -oh -oi2 -ol -oni -qo+ -r -ri0:0 -s- -t -tk -tl -tsmca+", " $fileTypesArgumentLines", " -x`"*\$($MyInvocation.MyCommand.Name)`"", " -w`"$($env:TEMP)`"", " -ilog`"$errorLogFilePath`"", " -- `"$outputRarFilePath`"", " -- `"$($inputFile.FullName)`"" ) Write-Host "Compressing file with $size mb dictionary dize: `"$($inputFile.Name)`"..." #Write-Host "" #Write-Host "rar.exe arguments:" -ForegroundColor DarkGray #Write-Host ($arguments -join [Environment]::NewLine) -ForegroundColor DarkGray $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = $rarExecutablePath $psi.Arguments = $arguments -join ' ' $psi.RedirectStandardOutput = $false $psi.UseShellExecute = $false $psi.CreateNoWindow = $false $process = [System.Diagnostics.Process]::Start($psi) $process.WaitForExit() $outputRarFile = New-Object System.IO.FileInfo($outputRarFilePath) $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFile.Length Write-Host "" Write-Host "Created rar with file name: $($outputRarFile.Name) ($formattedOutputRarFileSize)" -ForegroundColor DarkGreen if ($toleranceSizeDiff -ne $null) { if ($createdRarFiles.Count -ne 0) { $outputRarFileMB = [Math]::Floor($outputRarFile.Length / $toleranceSizeDiff) $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFile.Length foreach ($rarFile in $createdRarFiles) { if ($rarFile.Exists) { $sizeMB = [Math]::Floor($rarFile.Length / $toleranceSizeDiff) $formattedRarFileSize = Format-FileSize -fileSize $rarFile.Length if ($outputRarFileMB -eq $sizeMB) { Write-Host "" Write-Host "File size of this created RAR file ($formattedOutputRarFileSize) is within the $toleranceSizeDiff tolerance difference" -ForegroundColor DarkGray Write-Host "than a previously created RAR file ($formattedRarFileSize) with smaller dictionary size..." -ForegroundColor DarkGray Write-Host "Deleting file: `"$($outputRarFile.Name)`" ($formattedOutputRarFileSize)..." -ForegroundColor Yellow if ($sendRarFilesToRecycleBin) { [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin') } else { [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'DeletePermanently') } Write-Host "Deletion completed." -ForegroundColor Yellow } } } } } if (Test-Path -LiteralPath $outputRarFile.FullName -PathType Leaf) { $createdRarFiles.Add($outputRarFile) } Write-Host "" } if ($keepOnlySmallestRarFile -and $createdRarFiles.Count -gt 0) { $existingFiles = $createdRarFiles | Where-Object { $_.Exists } if ($existingFiles.Count -gt 0) { Write-Host "`$keepOnlySmallestRarFile variable is `$True. Comparing file sizes of created RAR files..." -ForegroundColor Yellow Write-Host "" $smallestFile = $existingFiles | Sort-Object Length | Select-Object -First 1 foreach ($file in $existingFiles) { if ($file -ne $smallestFile) { $formattedFileSize = Format-FileSize -fileSize $file.Length Write-Host "Deleting file: `"$($file.Name)`" ($formattedFileSize)..." -ForegroundColor Yellow if ($sendRarFilesToRecycleBin) { [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin') } else { [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'DeletePermanently') } Write-Host "Deletion completed." -ForegroundColor Yellow Write-Host "" } } $formattedSmallestFileSize = Format-FileSize -fileSize $smallestFile.Length Write-Host "Smallest file kept: $($smallestFile.Name) ($formattedSmallestFileSize)" -ForegroundColor Green Write-Host "" } } } } function Format-FileSize { param( [long]$fileSize ) $buffer = New-Object System.Text.StringBuilder 260 [Win32Functions]::StrFormatByteSizeW($fileSize, $buffer, $buffer.Capacity) | Out-Null return $buffer.ToString() } function Show-GoodbyeScreen { Write-Host "Operation Completed!" -BackgroundColor Black -ForegroundColor Green Write-Host "" Write-Host "Press any key to exit..." $key = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown") Exit(0) } <# =========================================================================================== | | | Main | | | =========================================================================================== #> [System.Console]::Title = "RAR Multi-Compression Test Tool (Files) - by Elektro" #[System.Console]::SetWindowSize(150, 45) [CultureInfo]::CurrentUICulture = "en-US" try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { } Show-WelcomeScreen Confirm-Continue Compress-Files Show-GoodbyeScreen