elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)  (Leído 4,943 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
[APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« en: 2 Marzo 2024, 12:47 pm »

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
  1. <#
  2. ===========================================================================================
  3. |                                                                                         |
  4. |                                        Variables                                        |
  5. |                                                                                         |
  6. ===========================================================================================
  7. #>
  8.  
  9. $rarExecutablePath = "C:\Program Files\WinRAR\rar.exe"
  10. $dictionarySizes   = @(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048)
  11. $toleranceSizeDiff = "1MB"
  12. $keepOnlySmallestRarFile  = $true
  13. $sendRarFilesToRecycleBin = $false
  14.  
  15. $compressedFileTypesArchive = @(
  16.    "7z" , "arc", "bz2" , "bzip", "bzip2",
  17.    "gz" , "gz2", "gza" , "gzi" , "gzip" ,
  18.    "lha", "lz" , "lz4" , "lzh" , "lzma" ,
  19.    "rar", "sfx", "tgz" , "tlz" , "tlzma",
  20.    "uha", "zip", "zipx", "zpaq"
  21. )
  22.  
  23. $compressedFileTypesAudio = @(
  24.    "aac", "ac3", "fla","flac",
  25.    "m4a", "mp3", "ogg", "ogm",
  26.    "usm", "wma"
  27. )
  28.  
  29. $compressedFileTypesVideo = @(
  30.    "asf", "avc", "avi" , "bik" , "bk2" , "f4v" , "flv" ,
  31.    "m1v", "m2t", "m2ts", "m2v" , "m4v" , "mpv4",
  32.    "mkv", "mov", "mp4" , "mpeg", "mpg" , "mts" ,
  33.    "qt" , "ts" , "vob" , "vp6" , "webm", "wmv"
  34. )
  35.  
  36. $compressedFileTypesOther = @(
  37.    "avif", "jpeg", "jpg" , "gif" , "pdf",
  38.    "pam" , "paq6", "paq7", "paq8",
  39.    "par" , "par2", "wad"
  40. )
  41.  
  42.  
  43. [string]$fileTypesToKeepUncompressed = (
  44.    $compressedFileTypesArchive +
  45.    $compressedFileTypesAudio +
  46.    $compressedFileTypesVideo +
  47.    $compressedFileTypesOther
  48. ) -join ';'
  49.  
  50. <#
  51. ===========================================================================================
  52. |                                                                                         |
  53. |                    rar.exe commands (only those used in this script)                    |
  54. |                                                                                         |
  55. ===========================================================================================
  56.  
  57. <Commands>
  58.  a             Add files to archive
  59.  
  60. <Switches>
  61.  -am[s,r]       Archive name and time [save, restore]
  62.  -c-            Disable comments show
  63.  -cfg-          Ignore configuration file and RAR environment variable.
  64.  -dh            Open shared files
  65.  -ep1           Exclude base directory from names
  66.  -ht[b|c]       Select hash type [BLAKE2,CRC32] for file checksum
  67.  -id[c,d,n,p,q] Display or disable messages
  68.  -ilog[name]    Log errors to file
  69.  -isnd[-]       Control notification sounds
  70.  -m<0..5>       Set compression level (0-store...3-default...5-maximal)
  71.  -ma[4|5]       Specify a version of archiving format
  72.  -md<n>[k,m,g]  Dictionary size in KB, MB or GB
  73.  -ms[list]      Specify file types to store.
  74.  -o[+|-]        Set the overwrite mode
  75.  -oc            Set NTFS Compressed attribute.
  76.  -oh            Save hard links as the link instead of the file
  77.  -oi[0-4][:min] Save identical files as references
  78.  -ol[a]         Process symbolic links as the link [absolute paths]
  79.  -oni           Allow potentially incompatible names
  80.  -qo[-|+]       Add quick open information [none|force]
  81.  -r             Recurse subdirectories
  82.  -ri<P>[:<S>]   Set priority (0-default,1-min..15-max) and sleep time in ms
  83.  -s-            Disable solid archiving
  84.  -t             Test files after archiving
  85.  -tk            Keep original archive time
  86.  -tl            Set archive time to newest file
  87.  -ts[m,c,a,p]   Save or restore time (modification, creation, access, preserve)
  88.  -u             Update files
  89.  -w<path>       Assign work directory
  90. #>
  91.  
  92. <#
  93. ===========================================================================================
  94. |                                                                                         |
  95. |                                        .NET Code                                        |
  96. |                                                                                         |
  97. ===========================================================================================
  98. #>
  99.  
  100. Add-Type -TypeDefinition @"
  101. using System;
  102. using System.Runtime.InteropServices;
  103.  
  104. public class Win32Functions {
  105.    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
  106.    public static extern long StrFormatByteSizeW(long fileSize, System.Text.StringBuilder buffer, int bufferSize);
  107. }
  108. "@
  109.  
  110. <#
  111. ===========================================================================================
  112. |                                                                                         |
  113. |                                    Functions                                            |
  114. |                                                                                         |
  115. ===========================================================================================
  116. #>
  117. function Show-WelcomeScreen {
  118.    Clear-Host
  119.    Write-Host ""
  120.    Write-Host " $($host.ui.RawUI.WindowTitle)"
  121.    Write-Host " +==========================================================+"
  122.    Write-Host " |                                                          |"
  123.    Write-Host " | This script will use RAR.exe to compress each directory  |"
  124.    Write-Host " | in the current working directory individually, each      |"
  125.    Write-Host " | using different dictionary sizes, with max. compression, |"
  126.    Write-Host " | generating this way multiple RAR files for evaluating    |"
  127.    Write-Host " | compression rates on these dictionary sizes.             |"
  128.    Write-Host " |                                                          |"
  129.    Write-Host " +==========================================================+"
  130.    Write-Host ""
  131.    Write-Host " Script Settings            " -ForegroundColor DarkGray
  132.    Write-Host " ===========================" -ForegroundColor DarkGray
  133.    Write-Host " RAR Executable Path: $([System.IO.Path]::GetFullPath($rarExecutablePath))" -ForegroundColor Gray
  134.    Write-Host "" -ForegroundColor DarkGray
  135.    Write-Host " Dictionary Sizes (Megabyte): $($dictionarySizes -join ', ')" -ForegroundColor Gray
  136.    Write-Host " The script will create a RAR archive for each specified dictionary size." -ForegroundColor DarkGray
  137.    Write-Host "" -ForegroundColor DarkGray
  138.    Write-Host " File Types To Keep Uncompressed: `$keepCompressedFileTypesUncompressed" -ForegroundColor Gray
  139.    Write-Host " The script will instruct RAR to don't compress the specified known compressed file types." -ForegroundColor DarkGray
  140.    Write-Host " (See `$keepCompressedFileTypesUncompressed variable definition to manage the file types)" -ForegroundColor DarkGray
  141.    Write-Host "" -ForegroundColor DarkGray
  142.    Write-Host " Tolerance File Size Difference: $toleranceSizeDiff" -ForegroundColor Gray
  143.    Write-Host " Any newly created RAR file whose file size compared to previously   " -ForegroundColor DarkGray
  144.    Write-Host " created RAR files is within the specified tolerance value, it will be deleted." -ForegroundColor DarkGray
  145.    Write-Host " For example, if `$toleranceSizeDiff value is 1MB:" -ForegroundColor DarkGray
  146.    Write-Host " If a created RAR file of 32 MB dict. size has a file size of 100 MB," -ForegroundColor DarkGray
  147.    Write-Host " and then a newly created RAR file of 64 MB dict. size has a file size of 99 MB, " -ForegroundColor DarkGray
  148.    Write-Host " the RAR file of 64 MB dict. size will be deleted because it only differs in 1MB or less." -ForegroundColor DarkGray
  149.    Write-Host "" -ForegroundColor DarkGray
  150.    Write-Host " Keep only smallest rar file: $keepOnlySmallestRarFile" -ForegroundColor Gray
  151.    Write-Host " If True, the script will delete any newly created RAR file " -ForegroundColor DarkGray
  152.    Write-Host " whose file size is bigger than previously created RAR files." -ForegroundColor DarkGray
  153.    Write-Host " Note: it takes into account the specified `$toleranceSizeDiff value." -ForegroundColor DarkGray
  154.    Write-Host "" -ForegroundColor DarkGray
  155.    Write-Host " Send RAR files to recycle bin: $sendRarFilesToRecycleBin" -ForegroundColor Gray
  156.    Write-Host " If True, the script will send RAR files to recycle bin instead of permanently deleting them." -ForegroundColor DarkGray
  157.    Write-Host ""
  158. }
  159.  
  160. function Confirm-Continue {
  161.    Write-Host " Press 'Y' key to continue or 'N' to exit."
  162.    Write-Host ""
  163.    Write-Host " -Continue? (Y/N)"
  164.    do {
  165.        $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  166.        $char = $key.Character.ToString().ToUpper()
  167.        if ($char -ne "Y" -and $char -ne "N") {
  168.            [console]::beep(1500, 500)
  169.        }
  170.    } while ($char -ne "Y" -and $char -ne "N")
  171.    if ($char -eq "N") {Exit(1)} else {Clear-Host}
  172. }
  173.  
  174. function Compress-Files {
  175.    Add-Type -AssemblyName Microsoft.VisualBasic
  176.  
  177.    $dictionarySizes = $dictionarySizes | Sort-Object
  178.  
  179.    # Partir y formatear la cadena de file types para acomodarlo a la linea de argumentos de rar.exe
  180.    if (-not [String]::IsNullOrEmpty($fileTypesToKeepUncompressed)) {
  181.        $fileTypeTokens = $fileTypesToKeepUncompressed -split ';'
  182.        $fileTypesArgumentLines = @()
  183.        for ($i = 0; $i -lt $fileTypeTokens.Count; $i += 20) {
  184.            $fileTypesArgumentLines += "-ms" + ($fileTypeTokens[$i..($i + 19)] -join ';') + [Environment]::NewLine
  185.        }
  186.        if ($fileTypesArgumentLines.Count -gt 0) {
  187.            $fileTypesArgumentLines[-1] = $fileTypesArgumentLines[-1] -replace [Environment]::NewLine, ''
  188.        }
  189.    } else {
  190.        $fileTypesArgumentLines = "-ms "
  191.    }
  192.  
  193.    foreach ($dir in Get-ChildItem -LiteralPath "$PSScriptRoot" -Directory) {
  194.  
  195.        $dirSizeBytes = (Get-ChildItem -LiteralPath "$($dir.FullName)" -Recurse | Measure-Object -Property Length -sum).Sum
  196.  
  197.        # Keeps track of created rar files by rar.exe
  198.        $createdRarFiles = New-Object System.Collections.Generic.List[System.IO.FileInfo]
  199.  
  200.        foreach ($size in $dictionarySizes) {
  201.  
  202.            if (($size -ne $dictionarySizes[0]) -and ($dirSizeBytes * 4) -le ($size * 1MB)) {
  203.                $formattedDirSize = Format-FileSize -fileSize $dirSizeBytes
  204.                Write-Host "Ignoring compression with too big dictionary size of $size mb for a $formattedDirSize directory: `"$($dir.FullName)`"..." -ForegroundColor Yellow
  205.                continue
  206.            }
  207.  
  208.            $outputRarFilePath   = "$($dir.FullName)_$($size)mb.rar"
  209.            $errorLogFilePath = "$($dir.FullName)_$($size)mb_error.log"
  210.  
  211.            $arguments = @(
  212.                " a -u -ams -c- -cfg- -dh -ep1 -htb -idcdn -isnd- -iver -m5 -ma5 -md$($size)m",
  213.                " -o+ -oc -oh -oi2 -ol -oni -qo+ -r -ri0:0 -s- -t -tk -tl -tsmca+",
  214.                " $fileTypesArgumentLines",
  215.                " -x`"*\$($MyInvocation.MyCommand.Name)`"",
  216.                " -w`"$($env:TEMP)`"",
  217.                " -ilog`"$errorLogFilePath`"",
  218.                " -- `"$outputRarFilePath`"",
  219.                " -- `"$($dir.FullName)\*`""
  220.            )
  221.  
  222.            Write-Host "Compressing directory with $size mb dictionary dize: `"$($dir.Name)`"..."
  223.            #Write-Host ""
  224.            #Write-Host "rar.exe arguments:" -ForegroundColor DarkGray
  225.            #Write-Host ($arguments -join [Environment]::NewLine) -ForegroundColor DarkGray
  226.  
  227.            $psi = New-Object System.Diagnostics.ProcessStartInfo
  228.            $psi.FileName = $rarExecutablePath
  229.            $psi.Arguments = $arguments -join ' '
  230.            $psi.RedirectStandardOutput = $false
  231.            $psi.UseShellExecute = $false
  232.            $psi.CreateNoWindow = $false
  233.  
  234.            $process = [System.Diagnostics.Process]::Start($psi)
  235.            $process.WaitForExit()
  236.  
  237.            $outputRarFile = New-Object System.IO.FileInfo($outputRarFilePath)
  238.            $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFile.Length
  239.            Write-Host ""
  240.            Write-Host "Created rar with file name: $($outputRarFile.Name) ($formattedOutputRarFileSize)" -ForegroundColor DarkGreen
  241.  
  242.            if ($toleranceSizeDiff -ne $null) {
  243.                if ($createdRarFiles.Count -ne 0) {
  244.                    $outputRarFileMB = [Math]::Floor($outputRarFile.Length / $toleranceSizeDiff)
  245.                    $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFile.Length
  246.  
  247.                    foreach ($rarFile in $createdRarFiles) {
  248.                        if ($rarFile.Exists) {
  249.                            $sizeMB = [Math]::Floor($rarFile.Length / $toleranceSizeDiff)
  250.                            $formattedRarFileSize = Format-FileSize -fileSize $rarFile.Length
  251.                            if ($outputRarFileMB -eq $sizeMB) {
  252.                                Write-Host ""
  253.                                Write-Host "File size of this created RAR file ($formattedOutputRarFileSize) is within the $toleranceSizeDiff tolerance difference" -ForegroundColor DarkGray
  254.                                Write-Host "than a previously created RAR file ($formattedRarFileSize) with smaller dictionary size..." -ForegroundColor DarkGray
  255.                                Write-Host "Deleting file: `"$($outputRarFile.Name)`" ($formattedOutputRarFileSize)..." -ForegroundColor Yellow
  256.                                if ($sendRarFilesToRecycleBin) {
  257.                                    [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin')
  258.                                } else {
  259.                                    [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'DeletePermanently')
  260.                                }
  261.                                Write-Host "Deletion completed." -ForegroundColor Yellow
  262.                            }
  263.                        }
  264.                    }
  265.                }
  266.            }
  267.  
  268.            if (Test-Path -LiteralPath $outputRarFile.FullName -PathType Leaf) {
  269.                $createdRarFiles.Add($outputRarFile)
  270.            }
  271.            Write-Host ""
  272.        }
  273.  
  274.        if ($keepOnlySmallestRarFile -and $createdRarFiles.Count -gt 0) {
  275.            $existingFiles = $createdRarFiles | Where-Object { $_.Exists }
  276.            if ($existingFiles.Count -gt 0) {
  277.                Write-Host "`$keepOnlySmallestRarFile variable is `$True. Comparing file sizes of created RAR files..." -ForegroundColor Yellow
  278.                Write-Host ""
  279.                $smallestFile = $existingFiles | Sort-Object Length | Select-Object -First 1
  280.                foreach ($file in $existingFiles) {
  281.                    if ($file -ne $smallestFile) {
  282.                        $formattedFileSize = Format-FileSize -fileSize $file.Length
  283.                        Write-Host "Deleting file: `"$($file.Name)`" ($formattedFileSize)..." -ForegroundColor Yellow
  284.                        if ($sendRarFilesToRecycleBin) {
  285.                            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin')
  286.                        } else {
  287.                            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'DeletePermanently')
  288.                        }
  289.                        Write-Host "Deletion completed." -ForegroundColor Yellow
  290.                        Write-Host ""
  291.                    }
  292.                }
  293.                $formattedSmallestFileSize = Format-FileSize -fileSize $smallestFile.Length
  294.                Write-Host "Smallest file kept: $($smallestFile.Name) ($formattedSmallestFileSize)" -ForegroundColor Green
  295.                Write-Host ""
  296.            }
  297.        }
  298.  
  299.    }
  300. }
  301.  
  302. function Format-FileSize {
  303.    param(
  304.        [long]$fileSize
  305.    )
  306.    $buffer = New-Object System.Text.StringBuilder 260
  307.    [Win32Functions]::StrFormatByteSizeW($fileSize, $buffer, $buffer.Capacity) | Out-Null
  308.    return $buffer.ToString()
  309. }
  310.  
  311. function Show-GoodbyeScreen {
  312.    Write-Host "Operation Completed!" -BackgroundColor Black -ForegroundColor Green
  313.    Write-Host ""
  314.    Write-Host "Press any key to exit..."
  315.    $key = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown")
  316.    Exit(0)
  317. }
  318.  
  319. <#
  320. ===========================================================================================
  321. |                                                                                         |
  322. |                                         Main                                            |
  323. |                                                                                         |
  324. ===========================================================================================
  325. #>
  326.  
  327. [System.Console]::Title = "RAR Multi-Compression Test Tool (Directories) - by Elektro"
  328. #[System.Console]::SetWindowSize(150, 45)
  329. [CultureInfo]::CurrentUICulture = "en-US"
  330.  
  331. try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { }
  332.  
  333. Show-WelcomeScreen
  334. Confirm-Continue
  335. Compress-Files
  336. Show-GoodbyeScreen
  337.  


« Última modificación: 3 Marzo 2024, 10:53 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #1 en: 19 Marzo 2024, 01:42 am »

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
  1. <#
  2. ===========================================================================================
  3. |                                                                                         |
  4. |                                        Variables                                        |
  5. |                                                                                         |
  6. ===========================================================================================
  7. #>
  8.  
  9. $rarExecutablePath = "${env:ProgramFiles}\WinRAR\rar.exe"
  10. $dictionarySizesMb = @(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048)
  11. $toleranceSizeDiff = 500kb
  12. $keepOnlySmallestRarFile  = $true
  13. $sendRarFilesToRecycleBin = $false
  14.  
  15. $compressedFileTypesArchive = @(
  16.    "7z" , "arc", "bz2" , "bzip", "bzip2",
  17.    "gz" , "gz2", "gza" , "gzi" , "gzip" ,
  18.    "lha", "lz" , "lz4" , "lzh" , "lzma" ,
  19.    "rar", "sfx", "tgz" , "tlz" , "tlzma",
  20.    "uha", "zip", "zipx", "zpaq"
  21. )
  22.  
  23. $compressedFileTypesAudio = @(
  24.    "aac", "ac3", "fla","flac",
  25.    "m4a", "mp3", "ogg", "ogm",
  26.    "usm", "wma"
  27. )
  28.  
  29. $compressedFileTypesVideo = @(
  30.    "asf", "avc", "avi" , "bik" , "bk2" , "f4v" , "flv" ,
  31.    "m1v", "m2t", "m2ts", "m2v" , "m4v" , "mpv4",
  32.    "mkv", "mov", "mp4" , "mpeg", "mpg" , "mts" ,
  33.    "qt" , "ts" , "vob" , "vp6" , "webm", "wmv"
  34. )
  35.  
  36. $compressedFileTypesOther = @(
  37.    "avif", "jpeg", "jpg" , "gif" , "pdf",
  38.    "pam" , "paq6", "paq7", "paq8",
  39.    "par" , "par2", "wad"
  40. )
  41.  
  42.  
  43. [string]$fileTypesToKeepUncompressed = (
  44.    $compressedFileTypesArchive +
  45.    $compressedFileTypesAudio +
  46.    $compressedFileTypesVideo +
  47.    $compressedFileTypesOther
  48. ) -join ';'
  49.  
  50. <#
  51. ===========================================================================================
  52. |                                                                                         |
  53. |                    rar.exe commands (only those used in this script)                    |
  54. |                                                                                         |
  55. ===========================================================================================
  56.  
  57. <Commands>
  58.  a             Add files to archive
  59.  
  60. <Switches>
  61.  -am[s,r]       Archive name and time [save, restore]
  62.  -c-            Disable comments show
  63.  -cfg-          Ignore configuration file and RAR environment variable.
  64.  -dh            Open shared files
  65.  -ep1           Exclude base directory from names
  66.  -ht[b|c]       Select hash type [BLAKE2,CRC32] for file checksum
  67.  -id[c,d,n,p,q] Display or disable messages
  68.  -ilog[name]    Log errors to file
  69.  -isnd[-]       Control notification sounds
  70.  -m<0..5>       Set compression level (0-store...3-default...5-maximal)
  71.  -ma[4|5]       Specify a version of archiving format
  72.  -md<n>[k,m,g]  Dictionary size in KB, MB or GB
  73.  -ms[list]      Specify file types to store.
  74.  -o[+|-]        Set the overwrite mode
  75.  -oc            Set NTFS Compressed attribute.
  76.  -oh            Save hard links as the link instead of the file
  77.  -oi[0-4][:min] Save identical files as references
  78.  -ol[a]         Process symbolic links as the link [absolute paths]
  79.  -oni           Allow potentially incompatible names
  80.  -qo[-|+]       Add quick open information [none|force]
  81.  -r             Recurse subdirectories
  82.  -ri<P>[:<S>]   Set priority (0-default,1-min..15-max) and sleep time in ms
  83.  -s-            Disable solid archiving
  84.  -t             Test files after archiving
  85.  -tk            Keep original archive time
  86.  -tl            Set archive time to newest file
  87.  -ts[m,c,a,p]   Save or restore time (modification, creation, access, preserve)
  88.  -u             Update files
  89.  -w<path>       Assign work directory
  90. #>
  91.  
  92. <#
  93. ===========================================================================================
  94. |                                                                                         |
  95. |                                        .NET Code                                        |
  96. |                                                                                         |
  97. ===========================================================================================
  98. #>
  99.  
  100. Add-Type -TypeDefinition @"
  101. using System;
  102. using System.Runtime.InteropServices;
  103.  
  104. public class Win32Functions {
  105.    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
  106.    public static extern long StrFormatByteSizeW(long fileSize, System.Text.StringBuilder buffer, int bufferSize);
  107. }
  108. "@
  109.  
  110. <#
  111. ===========================================================================================
  112. |                                                                                         |
  113. |                                    Functions                                            |
  114. |                                                                                         |
  115. ===========================================================================================
  116. #>
  117. function Format-FileSize {
  118.    param(
  119.        [long]$fileSize
  120.    )
  121.    $buffer = New-Object System.Text.StringBuilder 260
  122.    [Win32Functions]::StrFormatByteSizeW($fileSize, $buffer, $buffer.Capacity) | Out-Null
  123.    return $buffer.ToString()
  124. }
  125.  
  126. function Show-WelcomeScreen {
  127.    Clear-Host
  128.    Write-Host ""
  129.    Write-Host " $($host.ui.RawUI.WindowTitle)"
  130.    Write-Host " +==========================================================+"
  131.    Write-Host " |                                                          |"
  132.    Write-Host " | This script will use RAR.exe to compress each directory  |"
  133.    Write-Host " | in the current working directory individually, each      |"
  134.    Write-Host " | using different dictionary sizes, with max. compression, |"
  135.    Write-Host " | generating this way multiple RAR files for evaluating    |"
  136.    Write-Host " | compression rates on these dictionary sizes.             |"
  137.    Write-Host " |                                                          |"
  138.    Write-Host " +==========================================================+"
  139.    Write-Host ""
  140.    Write-Host " Script Settings            " -ForegroundColor DarkGray
  141.    Write-Host " ===========================" -ForegroundColor DarkGray
  142.    Write-Host " RAR Executable Path: $([System.IO.Path]::GetFullPath($rarExecutablePath))" -ForegroundColor Gray
  143.    Write-Host "" -ForegroundColor DarkGray
  144.    Write-Host " Dictionary Sizes (Megabyte): $($dictionarySizesMb -join ', ')" -ForegroundColor Gray
  145.    Write-Host " The script will create a RAR archive for each specified dictionary size." -ForegroundColor DarkGray
  146.    Write-Host "" -ForegroundColor DarkGray
  147.    Write-Host " File Types To Keep Uncompressed: `$keepCompressedFileTypesUncompressed" -ForegroundColor Gray
  148.    Write-Host " The script will instruct RAR to don't compress the specified known compressed file types." -ForegroundColor DarkGray
  149.    Write-Host " (See `$keepCompressedFileTypesUncompressed variable definition to manage the file types)" -ForegroundColor DarkGray
  150.    Write-Host "" -ForegroundColor DarkGray
  151.    Write-Host " Tolerance File Size Difference: $(Format-FileSize -fileSize $toleranceSizeDiff)" -ForegroundColor Gray
  152.    Write-Host " Any newly created RAR file whose file size compared to previously   " -ForegroundColor DarkGray
  153.    Write-Host " created RAR files is within the specified tolerance value, it will be deleted." -ForegroundColor DarkGray
  154.    Write-Host " For example, if `$toleranceSizeDiff value is 1MB:" -ForegroundColor DarkGray
  155.    Write-Host " If a created RAR file of 32 MB dict. size has a file size of 100 MB," -ForegroundColor DarkGray
  156.    Write-Host " and then a newly created RAR file of 64 MB dict. size has a file size of 99 MB, " -ForegroundColor DarkGray
  157.    Write-Host " the RAR file of 64 MB dict. size will be deleted because it only differs in 1MB or less." -ForegroundColor DarkGray
  158.    Write-Host "" -ForegroundColor DarkGray
  159.    Write-Host " Keep only smallest RAR file: $keepOnlySmallestRarFile" -ForegroundColor Gray
  160.    Write-Host " If True, the script will delete any newly created RAR file " -ForegroundColor DarkGray
  161.    Write-Host " whose file size is bigger than previously created RAR files." -ForegroundColor DarkGray
  162.    Write-Host " Note: it takes into account the specified `$toleranceSizeDiff value." -ForegroundColor DarkGray
  163.    Write-Host "" -ForegroundColor DarkGray
  164.    Write-Host " Send RAR files to recycle bin: $sendRarFilesToRecycleBin" -ForegroundColor Gray
  165.    Write-Host " If True, the script will send RAR files to recycle bin instead of permanently deleting them." -ForegroundColor DarkGray
  166.    Write-Host ""
  167. }
  168.  
  169. function Confirm-Continue {
  170.    Write-Host " Press 'Y' key to continue or 'N' to exit."
  171.    Write-Host ""
  172.    Write-Host " -Continue? (Y/N)"
  173.    do {
  174.        $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  175.        $char = $key.Character.ToString().ToUpper()
  176.        if ($char -ne "Y" -and $char -ne "N") {
  177.            [console]::beep(1500, 500)
  178.        }
  179.    } while ($char -ne "Y" -and $char -ne "N")
  180.    if ($char -eq "N") {Exit(1)} else {Clear-Host}
  181. }
  182.  
  183. function Compress-Files {
  184.    Add-Type -AssemblyName Microsoft.VisualBasic
  185.  
  186.    $dictionarySizesMb = $dictionarySizesMb | Sort-Object
  187.  
  188.    # Partir y formatear la cadena de file types para acomodarlo a la linea de argumentos de rar.exe
  189.    if (-not [String]::IsNullOrEmpty($fileTypesToKeepUncompressed)) {
  190.        $fileTypeTokens = $fileTypesToKeepUncompressed -split ';'
  191.        $fileTypesArgumentLines = @()
  192.        for ($i = 0; $i -lt $fileTypeTokens.Count; $i += 20) {
  193.            $fileTypesArgumentLines += "-ms" + ($fileTypeTokens[$i..($i + 19)] -join ';') + [Environment]::NewLine
  194.        }
  195.        if ($fileTypesArgumentLines.Count -gt 0) {
  196.            $fileTypesArgumentLines[-1] = $fileTypesArgumentLines[-1] -replace [Environment]::NewLine, ''
  197.        }
  198.    } else {
  199.        $fileTypesArgumentLines = "-ms "
  200.    }
  201.  
  202.    foreach ($dir in Get-ChildItem -LiteralPath "$PSScriptRoot" -Directory) {
  203.  
  204.        $dirSizeBytes = (Get-ChildItem -LiteralPath "$($dir.FullName)" -Recurse | Measure-Object -Property Length -sum).Sum
  205.  
  206.        # Keeps track of created rar files by rar.exe
  207.        $createdRarFiles = New-Object System.Collections.Generic.List[System.IO.FileInfo]
  208.  
  209.        foreach ($size in $dictionarySizesMb) {
  210.  
  211.            if (($size -ne $dictionarySizesMb[0]) -and ($dirSizeBytes * 4) -le ($size * 1MB)) {
  212.                $formattedDirSize = Format-FileSize -fileSize $dirSizeBytes
  213.                Write-Host "Ignoring compression with too big dictionary size of $size mb for a $formattedDirSize directory: `"$($dir.FullName)`"..." -ForegroundColor Yellow
  214.                continue
  215.            }
  216.  
  217.            $outputRarFilePath   = "$($dir.FullName)_$($size)mb.rar"
  218.            $errorLogFilePath = "$($dir.FullName)_$($size)mb_error.log"
  219.  
  220.            $arguments = @(
  221.                " a -u -ams -c- -cfg- -dh -ep1 -htb -idcdn -isnd- -iver -m5 -ma5 -md$($size)m",
  222.                " -o+ -oc -oh -oi2 -ol -oni -qo+ -r -ri0:0 -s- -t -tk -tl -tsmca+",
  223.                " $fileTypesArgumentLines",
  224.                " -x`"*\$($MyInvocation.MyCommand.Name)`"",
  225.                " -w`"$($env:TEMP)`"",
  226.                " -ilog`"$errorLogFilePath`"",
  227.                " -- `"$outputRarFilePath`"",
  228.                " -- `"$($dir.FullName)\*`""
  229.            )
  230.  
  231.            Write-Host "Compressing directory with $size mb dictionary size: `"$($dir.Name)`"..."
  232.            #Write-Host ""
  233.            #Write-Host "rar.exe arguments:" -ForegroundColor DarkGray
  234.            #Write-Host ($arguments -join [Environment]::NewLine) -ForegroundColor DarkGray
  235.  
  236.            $previousForegroundColor = $host.UI.RawUI.ForegroundColor
  237.            $host.UI.RawUI.ForegroundColor = "DarkGray"
  238.            $psi = New-Object System.Diagnostics.ProcessStartInfo
  239.            $psi.FileName = $rarExecutablePath
  240.            $psi.Arguments = $arguments -join ' '
  241.            $psi.RedirectStandardOutput = $false
  242.            $psi.UseShellExecute = $false
  243.            $psi.CreateNoWindow = $false
  244.  
  245.            $process = [System.Diagnostics.Process]::Start($psi)
  246.            $process.WaitForExit()
  247.            $host.UI.RawUI.ForegroundColor = $previousForegroundColor
  248.  
  249.            $outputRarFile = New-Object System.IO.FileInfo($outputRarFilePath)
  250.            $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFile.Length
  251.            Write-Host ""
  252.            Write-Host "Created rar with file name: $($outputRarFile.Name) ($formattedOutputRarFileSize) ($($outputRarFile.Length) bytes)" -ForegroundColor DarkGreen
  253.  
  254.            if ($toleranceSizeDiff -ne $null) {
  255.                if ($createdRarFiles.Count -ne 0) {
  256.                    $outputRarFileSize = $outputRarFile.Length
  257.                    $formattedOutputRarFileSize = Format-FileSize -fileSize $outputRarFileSize
  258.                    $formattedToleranceFileSize = Format-FileSize -fileSize $toleranceSizeDiff
  259.  
  260.                    foreach ($createdRarFile in $createdRarFiles) {
  261.                        if ($createdRarFile.Exists) {
  262.                            $createdRarFileSize = $createdRarFile.Length
  263.                            $formattedCreatedRarFileSize = Format-FileSize -fileSize $createdRarFileSize
  264.                            $diffSize = [Math]::Abs($createdRarFileSize - $outputRarFileSize)
  265.                            $formattedDiffSize = Format-FileSize -fileSize $diffSize
  266.  
  267.                            if (($outputRarFileSize + $toleranceSizeDiff) -ge $createdRarFileSize) {
  268.                                Write-Host ""
  269.                                Write-Host "Size of this created RAR file ($formattedOutputRarFileSize) ($outputRarFileSize bytes) is within the $formattedToleranceFileSize tolerance difference" -ForegroundColor Yellow
  270.                                Write-Host "than a previously created RAR file of $formattedCreatedRarFileSize ($createdRarFileSize bytes) with smaller dictionary size..." -ForegroundColor Yellow
  271.                                Write-Host "Size of this created RAR file only differs by $formattedDiffSize ($diffSize bytes)." -ForegroundColor Yellow
  272.                                Write-Host "Deleting file: `"$($outputRarFile.Name)`"..." -ForegroundColor Yellow
  273.                                if ($sendRarFilesToRecycleBin) {
  274.                                    [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin')
  275.                                } else {
  276.                                    [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($outputRarFile.FullName, 'OnlyErrorDialogs', 'DeletePermanently')
  277.                                }
  278.                                Write-Host "Deletion completed." -ForegroundColor Yellow
  279.                                break
  280.                            }
  281.                        }
  282.                    }
  283.                }
  284.            }
  285.  
  286.            if (Test-Path -LiteralPath $outputRarFile.FullName -PathType Leaf) {
  287.                $createdRarFiles.Add($outputRarFile)
  288.            }
  289.            Write-Host ""
  290.        }
  291.  
  292.        if ($keepOnlySmallestRarFile -and $createdRarFiles.Count -gt 0) {
  293.            $existingFiles = $createdRarFiles | Where-Object { $_.Exists }
  294.            if ($existingFiles.Count -gt 0) {
  295.                Write-Host "`$keepOnlySmallestRarFile variable is `$True. Comparing file sizes of created RAR files..." -ForegroundColor Yellow
  296.                Write-Host ""
  297.                $smallestFile = $existingFiles | Sort-Object Length | Select-Object -First 1
  298.                foreach ($file in $existingFiles) {
  299.                    if ($file -ne $smallestFile) {
  300.                        $formattedFileSize = Format-FileSize -fileSize $file.Length
  301.                        Write-Host "Deleting file: `"$($file.Name)`" ($formattedFileSize)..." -ForegroundColor Yellow
  302.                        if ($sendRarFilesToRecycleBin) {
  303.                            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'SendToRecycleBin')
  304.                        } else {
  305.                            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, 'OnlyErrorDialogs', 'DeletePermanently')
  306.                        }
  307.                        Write-Host "Deletion completed." -ForegroundColor Yellow
  308.                        Write-Host ""
  309.                    }
  310.                }
  311.                $formattedSmallestFileSize = Format-FileSize -fileSize $smallestFile.Length
  312.                Write-Host "Smallest file kept: $($smallestFile.Name) ($formattedSmallestFileSize)" -ForegroundColor Green
  313.                Write-Host ""
  314.            }
  315.        }
  316.  
  317.    }
  318. }
  319.  
  320. function Show-GoodbyeScreen {
  321.    Write-Host "Operation Completed!" -BackgroundColor Black -ForegroundColor Green
  322.    Write-Host ""
  323.    Write-Host "Press any key to exit..."
  324.    $key = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown")
  325.    Exit(0)
  326. }
  327.  
  328. <#
  329. ===========================================================================================
  330. |                                                                                         |
  331. |                                         Main                                            |
  332. |                                                                                         |
  333. ===========================================================================================
  334. #>
  335.  
  336. [System.Console]::Title = "RAR Multi-Compression Test Tool (Directories) - by Elektro"
  337. #[System.Console]::SetWindowSize(150, 45)
  338. [CultureInfo]::CurrentUICulture = "en-US"
  339.  
  340. try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { }
  341.  
  342. Show-WelcomeScreen
  343. Confirm-Continue
  344. Compress-Files
  345. Show-GoodbyeScreen
  346.  


« Última modificación: 19 Marzo 2024, 01:45 am por Eleкtro » En línea



zelarra

Desconectado Desconectado

Mensajes: 59


Ver Perfil
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #2 en: 19 Marzo 2024, 07:06 am »

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.

« Última modificación: 19 Marzo 2024, 07:11 am por zelarra » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #3 en: 19 Marzo 2024, 09:24 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.



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.

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.

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.
« Última modificación: 19 Marzo 2024, 09:29 am por Eleкtro » En línea



**Aincrad**


Desconectado Desconectado

Mensajes: 682



Ver Perfil WWW
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #4 en: 19 Marzo 2024, 15:53 pm »

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.

En línea



zelarra

Desconectado Desconectado

Mensajes: 59


Ver Perfil
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #5 en: 19 Marzo 2024, 20:04 pm »

Vale, pues muchas gracias por tomarte la molestia de contestar y también por compartir lo que vas haciendo. Saludos.
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.878



Ver Perfil
Re: [APORTE] [PowerShell] RAR.exe | Multi-Compression Test Tool (Para Directorios)
« Respuesta #6 en: 20 Marzo 2024, 09:34 am »

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.



Que malvado, je! ;D
« Última modificación: 20 Marzo 2024, 09:39 am por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines