1

I am testing a small script to compress files, I compile the script to an executable with "PowerGUI Script Editor", everything works perfect but when you go to run the. exe and compress the file, shows a progress bar, I would like to know how I can hide the progress bar indicating the compression, my code is:

$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
}
}

the progress bar that I want hide is this:

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

I really need help, I hope someone can help me to solve my problem, thanks

user3755486
  • 11
  • 1
  • 2

2 Answers2

3

The progress bar comes from the CopyHere method, not from PowerShell, so setting $ProgressPreference = 'SilentlyContinue' won't help. Theoretically you could pass a second parameter with value 4 to the function in order to suppress that dialog:

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

but as documented, that parameter is ignored for zip files:

Note In some cases, such as compressed (.zip) files, some option flags may be ignored by design.


If you have PowerShell 3 and .Net framework 4.5 you could use the ZipFile class instead of the Shell.Application object:

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

Otherwise try one of the other methods outlined in the answers to this question.

Community
  • 1
  • 1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

Ansgar is right but there is still a way to hide it.

You can hide it by searching for all the windows (while loop) with the title "Compressing..." and hide them.
But this is not enough because if the file is too small, you will not have the window and the while loop will run forever.
This problem is because CopyHere is asynchronous function.
To get over this this I also added a check to see when the file is not locked and then remove all the jobs.

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
E235
  • 11,560
  • 24
  • 91
  • 141