win_unzip: added support for Server core by using .net zip functions (#29272)
* win_unzip: added support for Server core by using .net zip functions
* fixed unzip behaviour with folders
(cherry picked from commit 5623e679b8
)
This commit is contained in:
parent
c3bf59eb79
commit
e842ac4e3f
2 changed files with 82 additions and 16 deletions
|
@ -46,6 +46,47 @@ $result = @{
|
||||||
src = $src -replace '\$',''
|
src = $src -replace '\$',''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function Extract-Zip($src, $dest) {
|
||||||
|
$archive = [System.IO.Compression.ZipFile]::Open($src, [System.IO.Compression.ZipArchiveMode]::Read, [System.Text.Encoding]::UTF8)
|
||||||
|
foreach ($entry in $archive.Entries) {
|
||||||
|
$archive_name = $entry.FullName
|
||||||
|
|
||||||
|
$entry_target_path = [System.IO.Path]::Combine($dest, $archive_name)
|
||||||
|
$entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path)
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path $entry_dir)) {
|
||||||
|
New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((-not ($entry_target_path.EndsWith("\") -or $entry_target_path.EndsWith("/"))) -and (-not $check_mode)) {
|
||||||
|
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $entry_target_path, $true)
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
$archive.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Extract-ZipLegacy($src, $dest) {
|
||||||
|
# [System.IO.Compression.ZipFile] was only added in .net 4.5, this is used
|
||||||
|
# when .net is older than that.
|
||||||
|
$shell = New-Object -ComObject Shell.Application
|
||||||
|
$zip = $shell.NameSpace([IO.Path]::GetFullPath($src))
|
||||||
|
$dest_path = $shell.NameSpace([IO.Path]::GetFullPath($dest))
|
||||||
|
|
||||||
|
$shell = New-Object -ComObject Shell.Application
|
||||||
|
|
||||||
|
if (-not $check_mode) {
|
||||||
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866.aspx
|
||||||
|
# From Folder.CopyHere documentation, 1044 means:
|
||||||
|
# - 1024: do not display a user interface if an error occurs
|
||||||
|
# - 16: respond with "yes to all" for any dialog box that is displayed
|
||||||
|
# - 4: do not display a progress dialog box
|
||||||
|
$dest_path.CopyHere($zip.Items(), 1044)
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
If ($creates -and (Test-Path -LiteralPath $creates)) {
|
If ($creates -and (Test-Path -LiteralPath $creates)) {
|
||||||
$result.skipped = $true
|
$result.skipped = $true
|
||||||
$result.msg = "The file or directory '$creates' already exists."
|
$result.msg = "The file or directory '$creates' already exists."
|
||||||
|
@ -67,22 +108,29 @@ If (-Not (Test-Path -LiteralPath $dest -PathType Container)){
|
||||||
}
|
}
|
||||||
|
|
||||||
If ($ext -eq ".zip" -And $recurse -eq $false) {
|
If ($ext -eq ".zip" -And $recurse -eq $false) {
|
||||||
Try {
|
# TODO: PS v5 supports zip extraction, use that if available
|
||||||
$shell = New-Object -ComObject Shell.Application
|
$use_legacy = $false
|
||||||
$zipPkg = $shell.NameSpace([IO.Path]::GetFullPath($src))
|
try {
|
||||||
$destPath = $shell.NameSpace([IO.Path]::GetFullPath($dest))
|
# determines if .net 4.5 is available, if this fails we need to fall
|
||||||
|
# back to the legacy COM Shell.Application to extract the zip
|
||||||
if (-not $check_mode) {
|
Add-Type -AssemblyName System.IO.Compression.FileSystem | Out-Null
|
||||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866.aspx
|
Add-Type -AssemblyName System.IO.Compression | Out-Null
|
||||||
# From Folder.CopyHere documentation, 1044 means:
|
} catch {
|
||||||
# - 1024: do not display a user interface if an error occurs
|
$use_legacy = $true
|
||||||
# - 16: respond with "yes to all" for any dialog box that is displayed
|
}
|
||||||
# - 4: do not display a progress dialog box
|
|
||||||
$destPath.CopyHere($zipPkg.Items(), 1044)
|
if ($use_legacy) {
|
||||||
|
try {
|
||||||
|
Extract-ZipLegacy -src $src -dest $dest
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'!. Method: COM Shell.Application, Exception: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Extract-Zip -src $src -dest $dest
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'!. Method: System.IO.Compression.ZipFile, Exception: $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
$result.changed = $true
|
|
||||||
} Catch {
|
|
||||||
Fail-Json -obj $result -message "Error unzipping '$src' to $dest! Msg: $($_.Exception.Message)"
|
|
||||||
}
|
}
|
||||||
} Else {
|
} Else {
|
||||||
# Check if PSCX is installed
|
# Check if PSCX is installed
|
||||||
|
@ -125,7 +173,11 @@ If ($ext -eq ".zip" -And $recurse -eq $false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
If ($delete_archive){
|
If ($delete_archive){
|
||||||
|
try {
|
||||||
Remove-Item $src -Recurse -Force -WhatIf:$check_mode
|
Remove-Item $src -Recurse -Force -WhatIf:$check_mode
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "failed to delete archive at '$src': $($_.Exception.Message)"
|
||||||
|
}
|
||||||
$result.removed = $true
|
$result.removed = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,26 @@
|
||||||
dest: C:\Program Files\sysinternals
|
dest: C:\Program Files\sysinternals
|
||||||
register: unzip_archive
|
register: unzip_archive
|
||||||
|
|
||||||
- name: Test unzip_archive
|
- name: get stat of an extracted file
|
||||||
|
win_stat:
|
||||||
|
path: C:\Program Files\sysinternals\procexp.exe
|
||||||
|
register: unzip_archive_file
|
||||||
|
|
||||||
|
- name: Test unzip_archive (check-mode)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- unzip_archive|changed == true
|
- unzip_archive|changed == true
|
||||||
- unzip_archive.removed == false
|
- unzip_archive.removed == false
|
||||||
|
- unzip_archive_file.stat.exists == false
|
||||||
|
when: in_check_mode
|
||||||
|
|
||||||
|
- name: Test unzip_archive (normal mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip_archive|changed == true
|
||||||
|
- unzip_archive.removed == false
|
||||||
|
- unzip_archive_file.stat.exists == true
|
||||||
|
when: not in_check_mode
|
||||||
|
|
||||||
- name: Unarchive sysinternals archive again, use creates
|
- name: Unarchive sysinternals archive again, use creates
|
||||||
win_unzip:
|
win_unzip:
|
||||||
|
|
Loading…
Reference in a new issue