Skip to content

Instantly share code, notes, and snippets.

@lantrix
Last active February 24, 2021 16:31
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lantrix/738ebfa616d5222a8b1db947793bc3fc to your computer and use it in GitHub Desktop.
Save lantrix/738ebfa616d5222a8b1db947793bc3fc to your computer and use it in GitHub Desktop.
PowerShell encoding Zip paths to use forward slash (Zip Spec) instead of backslash (Windows Style); for portable zip files - thanks to @sethjackson
# When using System.IO.Compression.ZipFile.CreateFromDirectory in PowerShell, it still uses backslashes in the zip paths
# despite this https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/mitigation-ziparchiveentry-fullname-path-separator
# Based upon post by Seth Jackson https://sethjackson.github.io/2016/12/17/path-separators/
#
# PowerShell 5 (WMF5) & 6
# Using class Keyword https://msdn.microsoft.com/powershell/reference/5.1/Microsoft.PowerShell.Core/about/about_Classes
#
Add-Type -AssemblyName System.Text.Encoding
Add-Type -AssemblyName System.IO.Compression.FileSystem
class FixedEncoder : System.Text.UTF8Encoding {
FixedEncoder() : base($true) { }
[byte[]] GetBytes([string] $s)
{
$s = $s.Replace("\\", "/");
return ([System.Text.UTF8Encoding]$this).GetBytes($s);
}
}
[System.IO.Compression.ZipFile]::CreateFromDirectory($dirToZip, $zipFilePath, [System.IO.Compression.CompressionLevel]::Optimal, $false, [FixedEncoder]::new())
#
# PowerShell 4 (WMF4)
# Using Add-Type cmdlet https://msdn.microsoft.com/en-us/powershell/reference/4.0/microsoft.powershell.utility/add-type
#
Add-Type -AssemblyName System.Text.Encoding
Add-Type -AssemblyName System.IO.Compression.FileSystem
$EncoderClass=@"
public class FixedEncoder : System.Text.UTF8Encoding {
public FixedEncoder() : base(true) { }
public override byte[] GetBytes(string s) {
s = s.Replace("\\", "/");
return base.GetBytes(s);
}
}
"@
Add-Type -TypeDefinition $EncoderClass
$Encoder = New-Object FixedEncoder
[System.IO.Compression.ZipFile]::CreateFromDirectory($dirToZip, $zipFilePath, [System.IO.Compression.CompressionLevel]::Optimal, $false, $Encoder)
@cmaahs
Copy link

cmaahs commented Jun 11, 2018

In order for these to work this line needs to be replaced:

s = s.Replace("\\", "/");

with

s = s.Replace("\", "/");

There is no need to escape the \ character here. Presumably that was the intention of the double backslash.

I made this modification and was able to ZIP a directory on Windows Server 2016 and expand the ZIP on Mac OSX 10.13.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment