Powershell - Как завершить / закрыть zip-файл в powershell - PullRequest
5 голосов
/ 09 февраля 2012

Я хочу создать zip-файл в powershell, добавить элементы в zip-файл, а затем получить сжатое содержимое этого zip-файла в байтах сразу после создания zip-файла в том же scipt. Проблема в том, что не похоже, что zip-приложение записало свое содержимое в файловую систему. Как закрыть / очистить zip-приложение, чтобы следующий оператор powershell мог получить доступ к вновь созданному zip-файлу?

Пример:

new-item -type File test.zip -force
$zip = ( get-item test.zip ).fullname
$app = new-object -com shell.application
$folder = $app.namespace( $zip )
$item = new-item file.txt -itemtype file -value "Mooo" -force
$folder.copyhere( $item.fullname )
dir test.zip # <---- Empty test.zip file
Get-Content -Encoding byte $zip | echo # <-- nothing echoed

"dir test.zip" показывает zip-файл без содержимого, поэтому Get-Content ничего не возвращает.

Обратите внимание, что это, похоже, проблема с асинхронным поведением действия copyhere. Если я буду спать после строки копирования, почтовый файл станет заполненным. Однако я не знаю, как долго нужно спать, и не хочу откладывать обработку.

Большое спасибо заранее!

Ответы [ 5 ]

1 голос
/ 14 мая 2012

У меня также была эта проблема, все, что вам нужно, это ждать, пока операция архивирования не будет завершена.Итак, я придумаю это решение, вы должны поместить этот код после выполнения командлета powerpack «$ folder.copyhere» или «Copy-ToZip».

    $isCompleted = $false
    $guid = [Guid]::NewGuid().ToString()
    $tmpFileName = $zipFileName + $guid
    # The main idea is to try to rename target ZIP file. If it success then archiving operation is complete.
    while(!$isCompleted)
    {
        start-sleep -seconds 1
        Rename-Item $zipFileName $tmpFileName -ea 0 #Try to rename with suppressing errors
        if (Test-Path $tmpFileName)
        {
            Rename-Item $tmpFileName $zipFileName #Rename it back
            $isCompleted = $true
        }
    }
1 голос
/ 09 февраля 2012

Возможно, вы захотите пересмотреть использование сторонней библиотеки.Однако, если вы должны использовать copyhere , попробуйте это:

new-item -type File test.zip -force
$zip = ( get-item test.zip ).fullname
$app = new-object -com shell.application
$folder = $app.namespace( $zip )
$item = new-item file.txt -itemtype file -value "Mooo" -force
$folder.copyhere( $item.fullname)
while($folder.Items().Item($item.Name) -Eq $null)
{
    start-sleep -seconds 0.01
    write-host "." -nonewline
}
dir test.zip # <---- Empty test.zip file
Get-Content -Encoding byte $zip 
0 голосов
/ 10 февраля 2012

Этот метод для архивации файлов не подходит для автоматизированных сценариев. Это имеет ограничения в Windows 2003 и Windows XP Server на 3 гигабайта. Кроме того, это не дает правильных ошибок.

0 голосов
/ 09 февраля 2012

Создайте файл в закрытии, чтобы переменная вышла из области видимости, а powershell закрыл файл ... если бы вы превратили эту часть в подпрограмму, то она естественным образом закрылась бы, когда вы вернетесь.

new-item -type File test.zip -force
{ 
  $zip = ( get-item test.zip ).fullname
  $app = new-object -com shell.application
  $folder = $app.namespace( $zip )
  $item = new-item file.txt -itemtype file -value "Mooo" -force
  $folder.copyhere( $item.fullname )
}
dir test.zip # <---- Empty test.zip file
Get-Content -Encoding byte $zip
0 голосов
/ 09 февраля 2012

попробуйте создать пустой почтовый файл следующим образом:

$zipfilename = "myzip.zip"
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))

Тогда остальная часть вашего кода.

этот код в моей коробке работает:

$zipfilename = "a.zip"
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
$app = new-object -com shell.application
$zip = ( get-item a.zip ).fullname
$folder = $app.namespace( $zip )
$item = new-item file.txt -itemtype file -value "Mooo" -force
$folder.copyhere( $item.fullname )

чтобы получить содержимое почтового индекса, используйте это:

$zipfilename = "myzip.zip"
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
$zipPackage.Items() | Select Path
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...