如何隐藏PowerShell中的进度条(压缩)?

时间:2014-06-19 08:12:26

标签: powershell compression zipfile

我正在测试一个用于压缩文件的小脚本,我使用" PowerGUI Script Editor"将脚本编译成可执行文件,一切都很完美但是当你去运行时。 exe和压缩文件,显示进度条,我想知道如何隐藏进度条指示压缩,我的代码是:

$srcdir = mysourcedir
$zipFilename = \zipfilename
$zipFilepath = $env:temp
$zipFile = "$zipFilepath$zipFilename"

#Prepare zip file
if(-not (test-path($zipFile))) {
set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipFile).IsReadOnly = $false  
} 

$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipFile)
$files = Get-ChildItem -Path $srcdir

foreach($file in $files) { 
$ProgressPreference = ’SilentlyContinue’
$zipPackage.CopyHere($file.FullName)
#using this method, sometimes files can be 'skipped'
#this 'while' loop checks each file is added before moving to the next
while($zipPackage.Items().Item($file.name) -eq $null){
$ProgressPreference = ’SilentlyContinue’
    Start-sleep -seconds 1
}
}

我要隐藏的进度条是:

http://i.stack.imgur.com/LlUVQ.png

我真的需要帮助,希望有人能帮助我解决我的问题,谢谢

2 个答案:

答案 0 :(得分:2)

进度条来自CopyHere方法,而非来自PowerShell,因此设置$ProgressPreference = 'SilentlyContinue'不会有帮助。从理论上讲,您可以将值为4的第二个参数传递给函数,以便禁止该对话框:

$zipPackage.CopyHere($file.FullName, 4)

但如文档所述,zip文件会忽略该参数:

  

注意在某些情况下,例如压缩(.zip)文件,设计可能会忽略某些选项标记。


如果您有PowerShell 3和.Net framework 4.5,则可以使用ZipFile类而不是Shell.Application对象:

Add-Type -Assembly System.IO.Compression.FileSystem
$cl = [IO.Compression.CompressionLevel]::Optimal
[IO.Compression.ZipFile]::CreateFromDirectory($srcdir, $zipFile, $cl, $false)

否则,请尝试this question的答案中列出的其他方法之一。

答案 1 :(得分:0)

Ansgar是对的,但仍有办法隐藏它。

您可以通过搜索所有窗口(while循环)并使用标题"压缩..."来隐藏它。并隐藏它们 但这还不够,因为如果文件太小,你将无法使用窗口,while循环将永远运行。
这个问题是因为CopyHere是异步函数 为了解决这个问题,我还添加了一个检查,以查看文件何时未锁定,然后删除所有作业。

Function Test-FileLock {
      param (
        [parameter(Mandatory=$true)][string]$Path
      )

      $oFile = New-Object System.IO.FileInfo $Path

      if ((Test-Path -Path $Path) -eq $false) {
        return $false
      }

      try {
        $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)

        if ($oStream) {
          $oStream.Close()
        }
        $false
      } catch {
        # file is locked by a process.
        return $true
      }
}


$scriptBlock = {
    $FORCEMINIMIZE_STATE   = 11
    $HIDE_STATE            = 0
    $MAXIMIZE_STATE        = 3
    $MINIMIZE_STATE        = 6
    $RESTORE_STATE         = 9
    $SHOW_STATE            = 5
    $SHOWDEFAULT_STATE     = 10
    $SHOWMAXIMIZED_STATE   = 3
    $SHOWMINIMIZED_STATE   = 2
    $SHOWMINNOACTIVE_STATE = 7
    $SHOWNA_STATE          = 8
    $SHOWNOACTIVATE_STATE  = 4
    $SHOWNORMAL_STATE      = 1

$member = @"
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@

    $script:showWindowAsync = Add-Type -memberDefinition $member -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru

    $continue = $true
    do{
        $processes = Get-Process | where {$_.MainWindowTitle -eq "Compressing..." }
        foreach($proc in $processes)
        {
            if(![string]::IsNullOrEmpty($proc))
            {
                $null = $showWindowAsync::ShowWindowAsync($proc.MainWindowHandle, $HIDE_STATE)
                $continue = $false
            }
        }
    }while($continue)
}

$job = Start-Job -ScriptBlock $scriptBlock

#############################################
# Your CopyHere function                    #
 $zipPackage.CopyHere($file.FullName)
###########################################

# Checking when the compression will finish
do{
    Start-Sleep 2
}while((Test-FileLock $zipPackage))

Stop-Job $job
Get-Job | Remove-Job