Create A Zip without the original directory locate

2019-09-16 09:00发布

问题:

I'm attempting to create a zip from from a directory that directly contains the contents of the source directory and not the source directory then the content, which will then be uploaded to Azure.

So I have C:\temp\aFolder, create a zip from that using either the Write-Zip PSCXE

write-zip c:\temp\test c:\temp\test2.zip

or the Create-7zip function

function create-7zip([String] $aDirectory, [String] $aZipfile){
    [string]$pathToZipExe = "C:\Program Files (x86)\7-zip\7z.exe";
    [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r";
   & $pathToZipExe $arguments;
}

create-7zip "c:\temp\test" "c:\temp\test.zip"

Both ways will create a ZIP archive with the source directory located within.

So it'll be: TEST.ZIP -> TEST -> myContent.

What I want is: TEST.ZIP -> myContent. Is this possible? I can't find anything on this.

Any ideas/help is greatly appreciated.

EDIT: Since I can't answer my own question

OH MY GOD. @MJOLNIR has saved me again, I JUST FOUND his answer on another post. I apologize.

The answer is to use (If you have .NET 4.5 installed)

$src = "c:\temp\test"
$dst = "c:\temp\test3.zip"
[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
[System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst)

Will produce the TEST.ZIP -> Contents.

回答1:

Note that the ZipFile class is not supported prior to .Net Framework 4.5.

Neither the latest and greatest Framework nor external tools are actually required, though. Something like this should also work:

$folder  = 'C:\temp\test'
$zipfile = 'C:\path\to\your.zip'

# create the zip file
$b = 'P', 'K', 5, 6 | % { [char]$_ }
$b += 1..18 | % { [char]0 }
[IO.File]::WriteAllBytes($zipfile, [byte[]]$b)

$app = New-Object -COM 'Shell.Application'

$src = $app.NameSpace($folder)
$dst = $app.NameSpace($zipfile)

# copy items from source folder to zip file
$dst.CopyHere($src.Items())

# wait for copying to complete
do {
  Start-Sleep -Milliseconds 200
} until ($src.Items().Count -eq $dst.Items().Count)