[APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)

Páginas: (1/2) > >>

Eleкtro:

El siguiente script desarrollado en PowerShell y dependiente del programa externo RAR.exe (WinRAR), sirve para comprimir cada directorio dentro del directorio actual de forma individual, con compresión máxima, y utilizando los tamaños de diccionario especificados.

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 directorios de video juegos para PC 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 directory  |"
--
   Write-Host " | in the current working directory individually, each      |"
--
   Write-Host " | using 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 ($dir in Get-ChildItem -LiteralPath "$PSScriptRoot" -Directory) {
--
 
--
       $dirSizeBytes = (Get-ChildItem -LiteralPath "$($dir.FullName)" -Recurse | Measure-Object -Property Length -sum).Sum
--
 
--
       # 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 ($dirSizeBytes * 4) -le ($size * 1MB)) {
--
               $formattedDirSize = Format-FileSize -fileSize $dirSizeBytes
--
               Write-Host "Ignoring compression with too big dictionary size of $size mb for a $formattedDirSize directory: `"$($dir.FullName)`"..." -ForegroundColor Yellow
--
               continue
--
           }
--
 
--
           $outputRarFilePath   = "$($dir.FullName)_$($size)mb.rar"
--
           $errorLogFilePath = "$($dir.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`"",
--
               " -- `"$($dir.FullName)\*`""
--
           )
--
 
--
           Write-Host "Compressing directory with $size mb dictionary dize: `"$($dir.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 (Directories) - 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
--
 
--


Eleкtro:

Comparto una versión actualizada del script. Las modificaciones se han basado en perfeccionar pequeños detalles y mejorar bastante la forma en que se compara el tamaño de los archivos ($toleranceSizeDiff).

Código
--
<#
--
===========================================================================================
--
|                                                                                         |
--
|                                        Variables                                        |
--
|                                                                                         |
--
===========================================================================================
--
#>
--
 
--
$rarExecutablePath = "${env:ProgramFiles}\WinRAR\rar.exe"
--
$dictionarySizesMb = @(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048)
--
$toleranceSizeDiff = 500kb
--
$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 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-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 directory  |"
--
   Write-Host " | in the current working directory individually, each      |"
--
   Write-Host " | using 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): $($dictionarySizesMb -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: $(Format-FileSize -fileSize $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
--
 
--
   $dictionarySizesMb = $dictionarySizesMb | 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 ($dir in Get-ChildItem -LiteralPath "$PSScriptRoot" -Directory) {
--
 
--
       $dirSizeBytes = (Get-ChildItem -LiteralPath "$($dir.FullName)" -Recurse | Measure-Object -Property Length -sum).Sum
--
 
--
       # Keeps track of created rar files by rar.exe
--
       $createdRarFiles = New-Object System.Collections.Generic.List[System.IO.FileInfo]
--
 
--
       foreach ($size in $dictionarySizesMb) {
--
 
--
           if (($size -ne $dictionarySizesMb[0]) -and ($dirSizeBytes * 4) -le ($size * 1MB)) {
--
               $formattedDirSize = Format-FileSize -fileSize $dirSizeBytes
--
               Write-Host "Ignoring compression with too big dictionary size of $size mb for a $formattedDirSize directory: `"$($dir.FullName)`"..." -ForegroundColor Yellow
--
               continue
--
           }
--
 
--
           $outputRarFilePath   = "$($dir.FullName)_$($size)mb.rar"
--
           $errorLogFilePath = "$($dir.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`"",
--
               " -- `"$($dir.FullName)\*`""
--
           )
--
 
--
           Write-Host "Compressing directory with $size mb dictionary size: `"$($dir.Name)`"..."
--
           #Write-Host ""
--
           #Write-Host "rar.exe arguments:" -ForegroundColor DarkGray
--
           #Write-Host ($arguments -join [Environment]::NewLine) -ForegroundColor DarkGray
--
 
--
           $previousForegroundColor = $host.UI.RawUI.ForegroundColor
--
           $host.UI.RawUI.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()
--
           $host.UI.RawUI.ForegroundColor = $previousForegroundColor
--
 
--
           $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) ($($outputRarFile.Length) bytes)" -ForegroundColor DarkGreen
--
 
--
           if ($toleranceSizeDiff -ne $null) {
--
               if ($createdRarFiles.Count -ne 0) {
--
                   $outputRarFileSize = $outputRarFile.Length
--
                   $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFileSize
--
                   $formattedToleranceFileSize = Format-FileSize -fileSize $toleranceSizeDiff
--
 
--
                   foreach ($createdRarFile in $createdRarFiles) {
--
                       if ($createdRarFile.Exists) {
--
                           $createdRarFileSize = $createdRarFile.Length
--
                           $formattedCreatedRarFileSize = Format-FileSize -fileSize $createdRarFileSize
--
                           $diffSize = [Math]::Abs($createdRarFileSize - $outputRarFileSize)
--
                           $formattedDiffSize = Format-FileSize -fileSize $diffSize
--
 
--
                           if (($outputRarFileSize + $toleranceSizeDiff) -ge $createdRarFileSize) {
--
                               Write-Host ""
--
                               Write-Host "Size of this created RAR file ($formattedOutputRarFileSize) ($outputRarFileSize bytes) is within the $formattedToleranceFileSize tolerance difference" -ForegroundColor Yellow
--
                               Write-Host "than a previously created RAR file of $formattedCreatedRarFileSize ($createdRarFileSize bytes) with smaller dictionary size..." -ForegroundColor Yellow
--
                               Write-Host "Size of this created RAR file only differs by $formattedDiffSize ($diffSize bytes)." -ForegroundColor Yellow
--
                               Write-Host "Deleting file: `"$($outputRarFile.Name)`"..." -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
--
                               break
--
                           }
--
                       }
--
                   }
--
               }
--
           }
--
 
--
           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 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 (Directories) - 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
--
 
--


zelarra:

Hola. He visto tu entrada y me ha interesado el tema porque yo estaba pensando en hacer algo similar pero con VBA.

Quería hacerte variaspreguntas:

1. Cuando comprimo un archivo o carpeta, creo un rar con WinRar y un 7zup y un zip con 7zip. Luego escojo el que menos ocupa. ¿Se podría añadir esta opción?

2. No busco tanto que me genere un archivo comprimido por cada archivo / carpeta dentro de la carpeta, sino poder elegir si quiero un archivo individual, una carpeta solo, o varios archivos o varias carpetas o varios archivos y carpetas, y esto que lo comprima en una carpeta (que aparezca en el archivo comprimido primero la carpeta), o sueltos (que cuando abra el archivo comprimido se vean ya los archivos y carpetas que contiene). ¿Se podría considerar esta opción?

Si hace falta capturas que complementen mis preguntas, al mediodía las comparto.

Saludos y gracias por el aporte.



Eleкtro:

Cita de: zelarra en 19 Marzo 2024, 07:06 am
--
Quería hacerte variaspreguntas:
--

Agradezco tus sugerencias, pero este aporte no se debe considerar un proyecto abierto a solicitudes de cambios. Ni siquiera se debe considerar un proyecto. (En GitHub si tengo proyectos, todos ellos abiertos a solicitudes, abajo en mi firma de usuario hay enlace a mi perfil de GitHub.)

El script está hecho a medida para cumplir con mis necesidades personales. Simplemente lo comparto en el foro para que le pueda servir a otras personas que puedan encontrarse en situaciones con cierta similtud, para que puedan adaptar el código a sus necesidades, mediante sus conocimientos de programación.

Dado el caso siempre puedo considerar implementar alguna sugerencia muy puntual que no implicase realizar muchos cambios al comportamiento del código, y que sirviese para un propósito generalizado, pero no voy a adaptar el código a las necesidades específicas de otras personas para acabar fabricando un nuevo script prácticamente desde cero, por el tiempo que ello conlleva.


Cita de: zelarra en 19 Marzo 2024, 07:06 am
--
creo un rar con WinRar y un 7zup y un zip con 7zip. Luego escojo el que menos ocupa.
--

La eficacia de compresión de 7zip es superior a la de WinRAR, lo que supone que, al utilizar el mismo tamaño de diccionario y una configuración de máxima compresión, 7zip siempre debería obtener mayor tasa de compresión que WinRAR, aunque fuesen solo un par de bytes de diferencia al comprimir formatos de archivos que ya estén muy comprimidos.

Cita de: zelarra en 19 Marzo 2024, 07:06 am
--
poder elegir si quiero un archivo individual, una carpeta solo, o varios archivos o varias carpetas o varios archivos y carpetas

--

El comportamiento de un script puede ser configurado mediante la implementación de parámetros a través de la línea de comandos. Pero este script trabaja con una configuración hardcoded, es decir, con valores definidos directamente dentro del código fuente, en la sección "VARIABLES", por lo que para configurar el comportamiento del script hay que editar dichos valores.

Lo que propones implicaría demasiados cambios. Lo siento. El script procesa las carpetas de forma secuencial, todas las carpetas que haya en el directorio actual, sin opción a permitir seleccionar solamente "X" carpetas para la compresión.

Ese tipo de personalización sería más óptimo implementarlo en una interfaz gráfica de usuario (GUI), pero no en un script como este.

Cita de: zelarra en 19 Marzo 2024, 07:06 am
--
y esto que lo comprima en una carpeta (que aparezca en el archivo comprimido primero la carpeta), o sueltos (que cuando abra el archivo comprimido se vean ya los archivos y carpetas que contiene).

--

Ese comportamiento lo puedes alterar en el script simplemente borrando o añadiendo el parámetro "-ep1" de RAR.exe:

Citar
--
 -ep1           Exclude base directory from names
--

El parámetro está añadido por defecto en el script:

Citar
--
Código:
--
$arguments = @(
    " a -u -ams -c- -cfg- -dh -ep1 -htb -idcdn -isnd- -iver -m5 -ma5 -md$($size)m",
    ...
--

--


Si estás trabajando en un script de VBA y necesitas ayuda, para eso está el foro. Siéntete libre de mostrar tus avances y realizar dudas puntuales para seguir avanzado.

Aténtamente,
Elektro.

**Aincrad**:

me acabas de dar una Idea con este script, un Ransomware que comprima los archivos con contraseña  >:D , una contraseña generada especialmente para cada directorio basado en su ruta y algun otro identificador, osea que si cambia de ruta el comprimido , F.



Páginas: (1/2) > >>