Windows Powershell中的io.compression.zipfile异常

Windows Powershell中的io.compression.zipfile异常,windows,powershell,command-line,compression,Windows,Powershell,Command Line,Compression,我正在使用powershell脚本自动归档目录及其子目录。我用的是一个非常简单的 Add-Type -AssemblyName "system.io.compression.filesystem" [io.compression.zipfile]::CreateFromDirectory($d, $destinationFilename) 在很大程度上,这正是我需要它做的;但是最近出现了空子目录的问题。这些空子目录以某种方式被压缩为文件,而不是目录 首先,还有其他人遇到过这种情

我正在使用powershell脚本自动归档目录及其子目录。我用的是一个非常简单的

    Add-Type -AssemblyName "system.io.compression.filesystem"
    [io.compression.zipfile]::CreateFromDirectory($d, $destinationFilename)
在很大程度上,这正是我需要它做的;但是最近出现了空子目录的问题。这些空子目录以某种方式被压缩为文件,而不是目录

  • 首先,还有其他人遇到过这种情况吗
  • 问题是否与此.NETAPI有关,或者是否存在环境问题
  • 我应该使用不同版本的::CreateFromDirectory函数吗

  • 谢谢你的帮助

    我正在使用Bryan的脚本,它做到了它所说的,并且也应该满足您的要求

    有很多参数可以使用,比如压缩类型、时间戳、确认

    # Purpose: Creates a .zip file of a file or folder.
    #
    # Sample: zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm]
    #
    # Params:
    # -target: The file or folder you would like to zip.
    #
    # -zip_to: The location where the zip file will be created. If an old version
    # exists, it will be deleted.
    #
    # -compression (optional): Sets the compression level for your zip file. Options:
    # a. fast - Higher process speed, larger file size (default option).
    # b. small - Slower process speed, smaller file size.
    # c. none - Fastest process speed, largest file size.
    #
    # -add_timestamp (optional): Applies a timestamp to the .zip file name.
    # By default, no timestamp is used.
    #
    # -confirm (optional): When provided, indicates that you would like to be
    # prompted when the zip process is finished.
    #
    # |Info|
    
    [CmdletBinding()]
    Param (
      [Parameter(Mandatory=$true,Position=0)]
      [string]$target,
    
      [Parameter(Mandatory=$true,Position=1)]
      [string]$zip_to,
    
      [Parameter(Mandatory=$false,Position=2)]
      [ValidateSet("fast","small","none")]
      [string]$compression,
    
      [Parameter(Mandatory=$false,Position=3)]
      [bool]$timestamp,
    
      [Parameter(Mandatory=$false,Position=4)]
      [bool]$confirm
    )
    
    #-----------------------------------------------------------------------------#
    function DeleteFileOrFolder
    { Param([string]$PathToItem)
    
      if (Test-Path $PathToItem)
      {
        Remove-Item ($PathToItem) -Force -Recurse;
      }
    }
    
    function DetermineCompressionLevel{
    [Reflection.Assembly]::LoadFile('C:\WINDOWS\System32\zipfldr.dll')
    Add-Type -Assembly System.IO.Compression.FileSystem
      $CompressionToUse = $null;
    
      switch($compression)
      {
        "fast" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest}
        "small" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Optimal}
        "none" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::NoCompression}
        default {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest}
      }
    
      return $CompressionToUse;
    }
    
    #-----------------------------------------------------------------------------#
    Write-Output "Starting zip process...";
    
    if ((Get-Item $target).PSIsContainer)
    {
      $zip_to = ($zip_to + "\" + (Split-Path $target -Leaf) + ".zip");
    }
    else{
    
      #So, the CreateFromDirectory function below will only operate on a $target
      #that's a Folder, which means some additional steps are needed to create a
      #new folder and move the target file into it before attempting the zip process. 
      $FileName = [System.IO.Path]::GetFileNameWithoutExtension($target);
      $NewFolderName = ($zip_to + "\" + $FileName)
    
      DeleteFileOrFolder($NewFolderName);
    
      md -Path $NewFolderName;
      Copy-Item ($target) $NewFolderName;
    
      $target = $NewFolderName;
      $zip_to = $NewFolderName + ".zip";
    }
    
    DeleteFileOrFolder($zip_to);
    
    if ($timestamp)
    {
      $TimeInfo = New-Object System.Globalization.DateTimeFormatInfo;
      $CurrentTimestamp = Get-Date -Format $TimeInfo.SortableDateTimePattern;
      $CurrentTimestamp = $CurrentTimestamp.Replace(":", "-");
      $zip_to = $zip_to.Replace(".zip", ("-" + $CurrentTimestamp + ".zip"));
    }
    
    $Compression_Level = (DetermineCompressionLevel);
    $IncludeBaseFolder = $false;
    
    [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" );
    [System.IO.Compression.ZipFile]::CreateFromDirectory($target, $zip_to, $Compression_Level, $IncludeBaseFolder);
    
    Write-Output "Zip process complete.";
    
    if ($confirm)
    {
      write-Output "Press any key to quit ...";
      $quit = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
    }
    
    用法:

    zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm]
    

    希望能有所帮助。

    我正在使用Bryan编写的脚本,它做到了它所说的,并且也应该满足您的要求

    有很多参数可以使用,比如压缩类型、时间戳、确认

    # Purpose: Creates a .zip file of a file or folder.
    #
    # Sample: zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm]
    #
    # Params:
    # -target: The file or folder you would like to zip.
    #
    # -zip_to: The location where the zip file will be created. If an old version
    # exists, it will be deleted.
    #
    # -compression (optional): Sets the compression level for your zip file. Options:
    # a. fast - Higher process speed, larger file size (default option).
    # b. small - Slower process speed, smaller file size.
    # c. none - Fastest process speed, largest file size.
    #
    # -add_timestamp (optional): Applies a timestamp to the .zip file name.
    # By default, no timestamp is used.
    #
    # -confirm (optional): When provided, indicates that you would like to be
    # prompted when the zip process is finished.
    #
    # |Info|
    
    [CmdletBinding()]
    Param (
      [Parameter(Mandatory=$true,Position=0)]
      [string]$target,
    
      [Parameter(Mandatory=$true,Position=1)]
      [string]$zip_to,
    
      [Parameter(Mandatory=$false,Position=2)]
      [ValidateSet("fast","small","none")]
      [string]$compression,
    
      [Parameter(Mandatory=$false,Position=3)]
      [bool]$timestamp,
    
      [Parameter(Mandatory=$false,Position=4)]
      [bool]$confirm
    )
    
    #-----------------------------------------------------------------------------#
    function DeleteFileOrFolder
    { Param([string]$PathToItem)
    
      if (Test-Path $PathToItem)
      {
        Remove-Item ($PathToItem) -Force -Recurse;
      }
    }
    
    function DetermineCompressionLevel{
    [Reflection.Assembly]::LoadFile('C:\WINDOWS\System32\zipfldr.dll')
    Add-Type -Assembly System.IO.Compression.FileSystem
      $CompressionToUse = $null;
    
      switch($compression)
      {
        "fast" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest}
        "small" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Optimal}
        "none" {$CompressionToUse = [System.IO.Compression.CompressionLevel]::NoCompression}
        default {$CompressionToUse = [System.IO.Compression.CompressionLevel]::Fastest}
      }
    
      return $CompressionToUse;
    }
    
    #-----------------------------------------------------------------------------#
    Write-Output "Starting zip process...";
    
    if ((Get-Item $target).PSIsContainer)
    {
      $zip_to = ($zip_to + "\" + (Split-Path $target -Leaf) + ".zip");
    }
    else{
    
      #So, the CreateFromDirectory function below will only operate on a $target
      #that's a Folder, which means some additional steps are needed to create a
      #new folder and move the target file into it before attempting the zip process. 
      $FileName = [System.IO.Path]::GetFileNameWithoutExtension($target);
      $NewFolderName = ($zip_to + "\" + $FileName)
    
      DeleteFileOrFolder($NewFolderName);
    
      md -Path $NewFolderName;
      Copy-Item ($target) $NewFolderName;
    
      $target = $NewFolderName;
      $zip_to = $NewFolderName + ".zip";
    }
    
    DeleteFileOrFolder($zip_to);
    
    if ($timestamp)
    {
      $TimeInfo = New-Object System.Globalization.DateTimeFormatInfo;
      $CurrentTimestamp = Get-Date -Format $TimeInfo.SortableDateTimePattern;
      $CurrentTimestamp = $CurrentTimestamp.Replace(":", "-");
      $zip_to = $zip_to.Replace(".zip", ("-" + $CurrentTimestamp + ".zip"));
    }
    
    $Compression_Level = (DetermineCompressionLevel);
    $IncludeBaseFolder = $false;
    
    [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" );
    [System.IO.Compression.ZipFile]::CreateFromDirectory($target, $zip_to, $Compression_Level, $IncludeBaseFolder);
    
    Write-Output "Zip process complete.";
    
    if ($confirm)
    {
      write-Output "Press any key to quit ...";
      $quit = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
    }
    
    用法:

    zipstuff.ps1 -target "C:\Projects\wsubi" -zip_to "C:\Users\Bryan\Desktop\wsubi" [-compression fast] [-timestamp] [-confirm]
    

    希望有帮助。

    考虑过了吗?我很乐意尝试一下。谢谢它使用的不是.Net framework库吗?您能描述一下发生这种情况的示例目录结构吗?似乎无法复制添加为文件的目录有什么特殊之处吗?是否仅在压缩网络共享上的文件时使用?是否只有名称中包含特定字符的文件?是否仅当您从特定服务器运行脚本时?您是否尝试过指定程序集的全名(例如,
    Add Type-AssemblyName'System.IO.Compression.FileSystem,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089'
    )?大家好,目录结构是一个专用的额外驱动器;但它不是一种共享资源。结构很深,但并不复杂。D:\Parent\…,其中空目录位于父目录下两层或两层以上的位置。空目录所在的位置没有特定的模式。注意,在某些情况下,即使目录是空的,它们也是必需的。没有它们会干扰其他流程。考虑过了吗?我很乐意尝试一下。谢谢它使用的不是.Net framework库吗?您能描述一下发生这种情况的示例目录结构吗?似乎无法复制添加为文件的目录有什么特殊之处吗?是否仅在压缩网络共享上的文件时使用?是否只有名称中包含特定字符的文件?是否仅当您从特定服务器运行脚本时?您是否尝试过指定程序集的全名(例如,
    Add Type-AssemblyName'System.IO.Compression.FileSystem,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089'
    )?大家好,目录结构是一个专用的额外驱动器;但它不是一种共享资源。结构很深,但并不复杂。D:\Parent\…,其中空目录位于父目录下两层或两层以上的位置。空目录所在的位置没有特定的模式。注意,在某些情况下,即使目录是空的,它们也是必需的。没有它们会干扰其他过程。哇!谢谢拉纳迪普,我真的很欣赏这个例子。我现在要试试这个。你经历过我遇到的问题吗?如果是这样,这个脚本解决了问题吗?@halciber:我知道网络的局限性,这就是为什么我开始使用
    zipfldr.dll
    。如果它不在那里,您可以从外部下载它,并可以像我在脚本
    C:\WINDOWS\System32\zipfldr.dll
    :)中给出的那样给出路径哇!谢谢拉纳迪普,我真的很欣赏这个例子。我现在要试试这个。你经历过我遇到的问题吗?如果是这样,这个脚本解决了问题吗?@halciber:我知道网络的局限性,这就是为什么我开始使用
    zipfldr.dll
    。如果它不在那里,您可以从外部下载它,并可以像我在脚本
    C:\WINDOWS\System32\zipfldr.dll中给出的那样给出路径