|
1 |
| -function requires_7zip($manifest, $architecture) { |
2 |
| - foreach($dlurl in @(url $manifest $architecture)) { |
3 |
| - if(file_requires_7zip $dlurl) { return $true } |
| 1 | +function Test-7ZipRequirement { |
| 2 | + [CmdletBinding(DefaultParameterSetName = "URL")] |
| 3 | + [OutputType([Boolean])] |
| 4 | + param( |
| 5 | + [Parameter(Mandatory = $true, ParameterSetName = "URL")] |
| 6 | + [String[]] |
| 7 | + $URL, |
| 8 | + [Parameter(Mandatory = $true, ParameterSetName = "File")] |
| 9 | + [String] |
| 10 | + $File |
| 11 | + ) |
| 12 | + if ($URL) { |
| 13 | + if (get_config 7ZIPEXTRACT_USE_EXTERNAL) { |
| 14 | + return $false |
| 15 | + } else { |
| 16 | + return ($URL | Where-Object { Test-7ZipRequirement -File $_ }).Count -gt 0 |
| 17 | + } |
| 18 | + } else { |
| 19 | + return $File -match '\.((gz)|(tar)|(tgz)|(lzma)|(bz)|(bz2)|(7z)|(rar)|(iso)|(xz)|(lzh)|(nupkg))$' |
4 | 20 | }
|
5 | 21 | }
|
6 | 22 |
|
7 |
| -function requires_lessmsi ($manifest, $architecture) { |
8 |
| - $useLessMsi = get_config MSIEXTRACT_USE_LESSMSI |
9 |
| - if (!$useLessMsi) { return $false } |
10 |
| - |
11 |
| - $(url $manifest $architecture | Where-Object { |
12 |
| - $_ -match '\.(msi)$' |
13 |
| - } | Measure-Object | Select-Object -exp count) -gt 0 |
14 |
| -} |
15 |
| - |
16 |
| -function file_requires_7zip($fname) { |
17 |
| - $fname -match '\.((gz)|(tar)|(tgz)|(lzma)|(bz)|(bz2)|(7z)|(rar)|(iso)|(xz)|(lzh)|(nupkg))$' |
18 |
| -} |
19 |
| - |
20 |
| -function extract_7zip($path, $to, $recurse) { |
21 |
| - $output = 7z x "$path" -o"$to" -y |
22 |
| - if($lastexitcode -ne 0) { abort "Exit code was $lastexitcode." } |
23 |
| - |
24 |
| - # check for tar |
25 |
| - $tar = (split-path $path -leaf) -replace '\.[^\.]*$', '' |
26 |
| - if($tar -match '\.tar$') { |
27 |
| - if(test-path "$to\$tar") { extract_7zip "$to\$tar" $to $true } |
| 23 | +function Test-LessMSIRequirement { |
| 24 | + [CmdletBinding()] |
| 25 | + [OutputType([Boolean])] |
| 26 | + param( |
| 27 | + [Parameter(Mandatory = $true)] |
| 28 | + [String[]] |
| 29 | + $URL |
| 30 | + ) |
| 31 | + if (get_config MSIEXTRACT_USE_LESSMSI) { |
| 32 | + return ($URL | Where-Object { $_ -match '\.msi$' }).Count -gt 0 |
| 33 | + } else { |
| 34 | + return $false |
28 | 35 | }
|
29 |
| - |
30 |
| - if($recurse) { Remove-Item $path } # clean up intermediate files |
31 |
| -} |
32 |
| - |
33 |
| -function extract_msi($path, $to) { |
34 |
| - $logfile = "$(split-path $path)\msi.log" |
35 |
| - $ok = run 'msiexec' @('/a', "`"$path`"", '/qn', "TARGETDIR=`"$to`"", "/lwe `"$logfile`"") |
36 |
| - if(!$ok) { abort "Failed to extract files from $path.`nLog file:`n $(friendly_path $logfile)" } |
37 |
| - if(test-path $logfile) { Remove-Item $logfile } |
38 | 36 | }
|
39 | 37 |
|
40 |
| -function lessmsi_config ($extract_dir) { |
41 |
| - $extract_fn = 'extract_lessmsi' |
42 |
| - if ($extract_dir) { |
43 |
| - $extract_dir = join-path SourceDir $extract_dir |
| 38 | +function Expand-7ZipArchive { |
| 39 | + [CmdletBinding()] |
| 40 | + param( |
| 41 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 42 | + [String] |
| 43 | + $Path, |
| 44 | + [Parameter(Position = 1)] |
| 45 | + [String] |
| 46 | + $DestinationPath = (Split-Path $Path), |
| 47 | + [Switch] |
| 48 | + $Removal |
| 49 | + ) |
| 50 | + $LogLocation = "$(Split-Path $Path)\7zip.log" |
| 51 | + if (get_config 7ZIPEXTRACT_USE_EXTERNAL) { |
| 52 | + try { |
| 53 | + 7z x "$Path" -o"$DestinationPath" -y | Out-File $LogLocation |
| 54 | + } catch [System.Management.Automation.CommandNotFoundException] { |
| 55 | + abort "Cannot find external 7Zip (7z.exe) while '7ZIPEXTRACT_USE_EXTERNAL' is 'true'!`nRun 'scoop config 7ZIPEXTRACT_USE_EXTERNAL false' or install 7Zip manually and try again." |
| 56 | + } |
44 | 57 | } else {
|
45 |
| - $extract_dir = "SourceDir" |
| 58 | + &(file_path 7zip 7z.exe) x "$Path" -o"$DestinationPath" -y | Out-File $LogLocation |
| 59 | + } |
| 60 | + if ($LASTEXITCODE -ne 0) { |
| 61 | + abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogLocation)" |
| 62 | + } |
| 63 | + if (Test-Path $LogLocation) { |
| 64 | + Remove-Item $LogLocation -Force |
| 65 | + } |
| 66 | + if ((strip_ext $Path) -match '\.tar$' -or $Path -match '\.tgz$') { |
| 67 | + # Check for tar |
| 68 | + $ArchivedFile = &(file_path 7zip 7z.exe) l "$Path" |
| 69 | + if ($LASTEXITCODE -eq 0) { |
| 70 | + $TarFile = $ArchivedFile[-3] -replace '.{53}(.*)', '$1' # get inner tar file name |
| 71 | + Expand-7ZipArchive "$DestinationPath\$TarFile" $DestinationPath -Removal |
| 72 | + } else { |
| 73 | + abort "Failed to list files in $Path.`nNot a 7Zip supported archive file." |
| 74 | + } |
| 75 | + } |
| 76 | + if ($Removal) { |
| 77 | + # Remove original archive file |
| 78 | + Remove-Item $Path -Force |
46 | 79 | }
|
47 |
| - |
48 |
| - $extract_fn, $extract_dir |
49 | 80 | }
|
50 | 81 |
|
51 |
| -function extract_lessmsi($path, $to) { |
52 |
| - Invoke-Expression "lessmsi x `"$path`" `"$to\`"" |
| 82 | +function Expand-MSIArchive { |
| 83 | + [CmdletBinding()] |
| 84 | + param( |
| 85 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 86 | + [String] |
| 87 | + $Path, |
| 88 | + [Parameter(Position = 1)] |
| 89 | + [String] |
| 90 | + $DestinationPath = (Split-Path $Path), |
| 91 | + [Switch] |
| 92 | + $Removal |
| 93 | + ) |
| 94 | + $LogLocation = "$(Split-Path $Path)\msi.log" |
| 95 | + if (get_config MSIEXTRACT_USE_LESSMSI) { |
| 96 | + &(file_path lessmsi lessmsi.exe) x "$Path" "$DestinationPath\" | Out-File $LogLocation |
| 97 | + if ($LASTEXITCODE -ne 0) { |
| 98 | + abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogLocation)" |
| 99 | + } |
| 100 | + if (Test-Path "$DestinationPath\SourceDir") { |
| 101 | + movedir "$DestinationPath\SourceDir" "$DestinationPath" | Out-Null |
| 102 | + } |
| 103 | + } else { |
| 104 | + $ok = run 'msiexec' @('/a', "`"$Path`"", '/qn', "TARGETDIR=`"$DestinationPath`"", "/lwe `"$LogLocation`"") |
| 105 | + if (!$ok) { |
| 106 | + abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogLocation)" |
| 107 | + } |
| 108 | + Remove-Item "$DestinationPath\$(fname $Path)" -Force |
| 109 | + } |
| 110 | + if (Test-Path $LogLocation) { |
| 111 | + Remove-Item $LogLocation -Force |
| 112 | + } |
| 113 | + if ($Removal) { |
| 114 | + # Remove original archive file |
| 115 | + Remove-Item $Path -Force |
| 116 | + } |
53 | 117 | }
|
54 | 118 |
|
55 |
| -function unpack_inno($fname, $manifest, $dir) { |
56 |
| - if (!$manifest.innosetup) { return } |
57 |
| - |
58 |
| - write-host "Unpacking innosetup... " -nonewline |
59 |
| - innounp -x -d"$dir\_scoop_unpack" "$dir\$fname" > "$dir\innounp.log" |
60 |
| - if ($lastexitcode -ne 0) { |
61 |
| - abort "Failed to unpack innosetup file. See $dir\innounp.log" |
| 119 | +function Expand-InnoArchive { |
| 120 | + [CmdletBinding()] |
| 121 | + param( |
| 122 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 123 | + [String] |
| 124 | + $Path, |
| 125 | + [Parameter(Position = 1)] |
| 126 | + [String] |
| 127 | + $DestinationPath = (Split-Path $Path), |
| 128 | + [Switch] |
| 129 | + $Removal |
| 130 | + ) |
| 131 | + $LogLocation = "$(Split-Path $Path)\innounp.log" |
| 132 | + &(file_path innounp innounp.exe) -x -d"$DestinationPath" -c'{app}' "$Path" -y | Out-File $LogLocation |
| 133 | + if ($LASTEXITCODE -ne 0) { |
| 134 | + abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogLocation)" |
| 135 | + } |
| 136 | + if (Test-Path $LogLocation) { |
| 137 | + Remove-Item $LogLocation -Force |
| 138 | + } |
| 139 | + if ($Removal) { |
| 140 | + # Remove original archive file |
| 141 | + Remove-Item $Path -Force |
62 | 142 | }
|
63 |
| - |
64 |
| - Get-ChildItem "$dir\_scoop_unpack\{app}" -r | Move-Item -dest "$dir" -force |
65 |
| - |
66 |
| - Remove-Item -r -force "$dir\_scoop_unpack" |
67 |
| - |
68 |
| - Remove-Item "$dir\$fname" |
69 |
| - Write-Host "done." -f Green |
70 | 143 | }
|
71 | 144 |
|
72 |
| -function extract_zip($path, $to) { |
73 |
| - if (!(test-path $path)) { abort "can't find $path to unzip"} |
74 |
| - try { add-type -assembly "System.IO.Compression.FileSystem" -ea stop } |
75 |
| - catch { unzip_old $path $to; return } # for .net earlier than 4.5 |
76 |
| - $retries = 0 |
77 |
| - while ($retries -le 10) { |
78 |
| - if ($retries -eq 10) { |
| 145 | +function Expand-ZipArchive { |
| 146 | + [CmdletBinding()] |
| 147 | + param( |
| 148 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 149 | + [String] |
| 150 | + $Path, |
| 151 | + [Parameter(Position = 1)] |
| 152 | + [String] |
| 153 | + $DestinationPath = (Split-Path $Path), |
| 154 | + [Switch] |
| 155 | + $Removal |
| 156 | + ) |
| 157 | + # All methods to unzip the file require .NET4.5+ |
| 158 | + if ($PSVersionTable.PSVersion.Major -lt 5) { |
| 159 | + Add-Type -AssemblyName System.IO.Compression.FileSystem |
| 160 | + try { |
| 161 | + [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, $DestinationPath) |
| 162 | + } catch [System.IO.PathTooLongException] { |
| 163 | + # try to fall back to 7zip if path is too long |
79 | 164 | if (7zip_installed) {
|
80 |
| - extract_7zip $path $to $false |
| 165 | + Expand-7ZipArchive $Path $DestinationPath -Removal |
81 | 166 | return
|
82 | 167 | } else {
|
83 |
| - abort "Unzip failed: Windows can't unzip because a process is locking the file.`nRun 'scoop install 7zip' and try again." |
| 168 | + abort "Unzip failed: Windows can't handle the long paths in this zip file.`nRun 'scoop install 7zip' and try again." |
84 | 169 | }
|
| 170 | + } catch [System.IO.IOException] { |
| 171 | + if (7zip_installed) { |
| 172 | + Expand-7ZipArchive $Path $DestinationPath -Removal |
| 173 | + return |
| 174 | + } else { |
| 175 | + abort "Unzip failed: Windows can't handle the file names in this zip file.`nRun 'scoop install 7zip' and try again." |
| 176 | + } |
| 177 | + } catch { |
| 178 | + abort "Unzip failed: $_" |
85 | 179 | }
|
86 |
| - if (isFileLocked $path) { |
87 |
| - write-host "Waiting for $path to be unlocked by another process... ($retries/10)" |
88 |
| - $retries++ |
89 |
| - Start-Sleep -s 2 |
90 |
| - } else { |
91 |
| - break |
92 |
| - } |
| 180 | + } else { |
| 181 | + # Use Expand-Archive to unzip in PowerShell 5+ |
| 182 | + Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force |
93 | 183 | }
|
94 |
| - |
95 |
| - try { |
96 |
| - [io.compression.zipfile]::extracttodirectory($path, $to) |
97 |
| - } catch [system.io.pathtoolongexception] { |
98 |
| - # try to fall back to 7zip if path is too long |
99 |
| - if (7zip_installed) { |
100 |
| - extract_7zip $path $to $false |
101 |
| - return |
102 |
| - } else { |
103 |
| - abort "Unzip failed: Windows can't handle the long paths in this zip file.`nRun 'scoop install 7zip' and try again." |
104 |
| - } |
105 |
| - } catch [system.io.ioexception] { |
106 |
| - if (7zip_installed) { |
107 |
| - extract_7zip $path $to $false |
108 |
| - return |
109 |
| - } else { |
110 |
| - abort "Unzip failed: Windows can't handle the file names in this zip file.`nRun 'scoop install 7zip' and try again." |
111 |
| - } |
112 |
| - } catch { |
113 |
| - abort "Unzip failed: $_" |
| 184 | + if ($Removal) { |
| 185 | + # Remove original archive file |
| 186 | + Remove-Item $Path -Force |
114 | 187 | }
|
115 | 188 | }
|
116 | 189 |
|
117 |
| -function unzip_old($path, $to) { |
118 |
| - # fallback for .net earlier than 4.5 |
119 |
| - $shell = (new-object -com shell.application -strict) |
120 |
| - $zipfiles = $shell.namespace("$path").items() |
121 |
| - $to = ensure $to |
122 |
| - $shell.namespace("$to").copyHere($zipfiles, 4) # 4 = don't show progress dialog |
| 190 | +function extract_7zip($path, $to, $removal) { |
| 191 | + Show-DeprecationMessage $MyInvocation 'Expand-7ZipArchive' |
| 192 | + Expand-7ZipArchive -Path $path -DestinationPath $to -Removal:$removal |
| 193 | +} |
| 194 | + |
| 195 | +function extract_msi($path, $to, $removal) { |
| 196 | + Show-DeprecationMessage $MyInvocation 'Expand-MSIArchive' |
| 197 | + Expand-MSIArchive -Path $path -DestinationPath $to -Removal:$removal |
| 198 | +} |
| 199 | + |
| 200 | +function extract_inno($path, $to, $removal) { |
| 201 | + Show-DeprecationMessage $MyInvocation 'Expand-InnoArchive' |
| 202 | + Expand-InnoArchive -Path $path -DestinationPath $to -Removal:$removal |
| 203 | +} |
| 204 | + |
| 205 | +function extract_zip($path, $to, $removal) { |
| 206 | + Show-DeprecationMessage $MyInvocation 'Expand-ZipArchive' |
| 207 | + Expand-ZipArchive -Path $path -DestinationPath $to -Removal:$removal |
123 | 208 | }
|
0 commit comments