使用Powershell在子文件夹中编辑zip文件内容

时间:2014-08-27 23:26:45

标签: xml powershell connection-string

我正在尝试更新从Excel文档创建的zip文件的内容。我想替换\ zipfile \ xl \ connections.xml。

的一些内容

此部分脚本将列出zip文件的内容:

$shell_app = new-object -com shell.application
$zip = “$destination\exceltemplates\Templates\Template1.xlsx.zip”
$zip_file=$shell_app.NameSpace($zip)
$zip_file.Items() | Select Path

但我尝试的每种更新方法都会产生错误。访问和更新zip文件中的文件需要的下一步是什么?

3 个答案:

答案 0 :(得分:5)

这不是很复杂。使用PowerShell v3.0或更高版本(以及标准.NET System.IO库)更容易。

# Parameters
$zipfileName = "E:\temp\WebsitePackage.zip"
$fileToEdit = "robots.txt"
$contents = "User-agent: *
Disallow: /"

# Open zip and find the particular file (assumes only one inside the Zip file)
Add-Type -assembly  System.IO.Compression.FileSystem
$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName,"Update")
$robotsFile = $zip.Entries.Where({$_.name -eq $fileToEdit})

# Update the contents of the file
$desiredFile = [System.IO.StreamWriter]($robotsFile).Open()
$desiredFile.BaseStream.SetLength(0)
$desiredFile.Write($contents)
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$zip.Dispose()
Write-Host "zip file updated"

下一个问题是如何快速检查您的更改是否成功?通过对脚本的简单修改,您可以读取Zip文件中的文件内容:

# Parameters
$zipfileName = "E:\temp\WebsitePackage.zip"
$fileToRead = "robots.txt"

# Open zip and find the particular file (assumes only one inside the Zip file)
Add-Type -assembly  System.IO.Compression.FileSystem
$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName,"Update")
$robotsFile = $zip.Entries.Where({$_.name -eq $fileToRead})

# Read the contents of the file
$desiredFile = [System.IO.StreamReader]($robotsFile).Open()
$text = $desiredFile.ReadToEnd()

# Output the contents
$text

$desiredFile.Close()
$desiredFile.Dispose()

# Close the zip file
$zip.Dispose()

本文提供了有用的背景材料:https://mcpmag.com/articles/2014/09/29/file-frontier-part-6.aspx

答案 1 :(得分:3)

搜索时,这是我发现的一个问题,所以我想我会冒昧地回答。在这个通用脚本中,不使用VB的调用,而是使用System.IO.Compression.FileSystem的dotnet导入。希望这有助于某人。谁知道,将来甚至可能是我! LOL

# The zip file to be updated
$file = Get-ChildItem ~\file.zip

# Load ZipFile (Compression.FileSystem) if necessary
try { $null = [IO.Compression.ZipFile] }
catch { [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') }

# Open zip file with update mode (Update, Read, Create -- are the options)
try { $fileZip = [System.IO.Compression.ZipFile]::Open( $file, 'Update' ) }
catch { throw "Another process has locked the '$file' file." }

# Finding the specific file within the zip file
<#
NOTE: These entries have the directories separated with a forward slash (/) instead of MS convention
of a backward slash (\).  Even though this is regex it seems the forward slash does not need to be escaped (\/).
NOTE2: Because this is regex '.*' must be used instead of a simple '*'
#>
$fileZip.Entries | Where-Object { $_.FullName -match '/subdir/.*/desiredfile.xml' }

# If needed, read the contents of specific file to $text and release the file so to use streamwriter later
$desiredFile = [System.IO.StreamReader]($fileZip.Entries | Where-Object { $_.FullName -match '/subdir/.*/desiredfile.xml' }).Open()
$text = $desiredFile.ReadToEnd()
$desiredFile.Close()
$desiredFile.Dispose()

# If needed, manipulate $text however for the update
$text = $text -replace '\n', [char]30

# Re-open the file this time with streamwriter
$desiredFile = [System.IO.StreamWriter]($fileZip.Entries | Where-Object { $_.FullName -match '/subdir/.*/desiredfile.xml' }).Open()

# If needed, zero out the file -- in case the new file is shorter than the old one
$desiredFile.BaseStream.SetLength(0)

# Insert the $text to the file and close
$desiredFile.Write($text -join "`r`n")
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$fileZip.Dispose()

答案 2 :(得分:1)

我必须在压缩的nuget包中替换版本xml文件(NuGetApp1.nuspec),如下所示:

zip中的原始文件内容:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
  <id>NuGetApp1</id>
  <version>1.1.3-dev22222</version>
  <title>NuGetApp1</title>
.....

必填:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
  <id>NuGetApp1</id>
  <version>1.0.0.0</version>
  <title>NuGetApp1</title>
.....

Powershell脚本:

$replaceWithVersion="1.0.0.0" 

$path = "c:\temp\testnuget"
$files = Get-ChildItem *.nupkg -Path $path 
foreach($fileNuget in $files)
{ 
    $target = $fileNuget.FullName -replace "[0-9]+(\.([0-9]+|\*)){1,4}", $replaceWithVersion
    Copy-Item $fileNuget.FullName -Destination $target
    $zipfileName = $target
    $fileToEdit = "*.nuspec"


    # Open zip and find the particular file (assumes only one inside the Zip file)
    $zip =  [System.IO.Compression.ZipFile]::Open($zipfileName,"Update")

    $nuspecFile = $zip.Entries.Where({$_.name -like $fileToEdit})

    # Read the contents of the file
    $desiredFile = [System.IO.StreamReader]($nuspecFile).Open()
    $text = $desiredFile.ReadToEnd()
    $desiredFile.Close()
    $desiredFile.Dispose()
    $text = $text -replace  '<version>[\s\S]*?<\/version>',"<version>$replaceWithVersion</version>"
    #update file with new content
    $desiredFile = [System.IO.StreamWriter]($nuspecFile).Open()
    $desiredFile.BaseStream.SetLength(0)

    # Insert the $text to the file and close
    $desiredFile.Write($text)
    $desiredFile.Flush()
    $desiredFile.Close()


   # Write the changes and close the zip file
   $zip.Dispose()
  Write-Host "zip file updated"
}

快乐狩猎: - )!