Powershell ZIP CopyHere抵制异步行为

时间:2017-12-15 15:50:09

标签: powershell namespaces zip kmz

在Powershell中,Shell-Application Namespace的CopyHere方法是异步的。我的主要目标是将KML文件转换为KMZ文件。执行此操作的过程是创建具有相同名称的ZIP文件,将KML复制到KMZ(压缩文件),然后将ZIP重命名为KMZ。不幸的是,异步意味着在CopyHere方法完成之前调用重命名函数。我找到了很多解决这个问题的例子。我找到的最干净的是:

$kmlPath = $global:directoryPath + "Test.kml"
$zip = $global:directoryPath + "Test.zip"
New-Item $zip -ItemType file
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zip)
$zipPackage.CopyHere($kmlPath, 16)

while($zipPackage.Items().Item($zip.Name) -Eq $null)
{
    start-sleep -seconds 1
    write-host "." -nonewline
}
write-host "."
Rename-Item -Path $zip -NewName $([System.IO.Path]::ChangeExtension($zip, ".kmz"))

这会响应以下错误:

  

异常调用"项目"用" 1"参数:"未实施   (HRESULT异常:0x80004001(E_NOTIMPL))"   + while($ zipPackage.Items()。Item($ zip.Name)-Eq $ null)   + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~       + CategoryInfo:NotSpecified:(:) [],MethodInvocationException       + FullyQualifiedErrorId:ComMethodTargetInvocation

我是否误用了这个特定包的Item方法?我很困惑为什么会出现""整齐地完成是不行的。我还尝试了Here提供的代码片段。在这种特殊情况下,它也会抱怨.Item方法。

1 个答案:

答案 0 :(得分:1)

我遇到的问题是试图找到拉链状态。

所以相反,我做了一段时间会触发......如果Zipfile是可打开的,文件名在里面。

function kml_to_kmz([string]$kmlPath){
    [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
    $kmlInfo = Get-ChildItem -Path $kmlPath
    $zipLocation = ($kmlInfo.Directory.FullName + '\' + $kmlInfo.Name.Remove($kmlInfo.Name.LastIndexOf('.')) + '.zip')
    New-item $zipLocation
    ((new-object -com shell.application).NameSpace($zipLocation)).CopyHere($kmlPath, 16)
    $trigger = $false
    while ($trigger -eq $false){
        try{
            $zip = [IO.Compression.ZipFile]::OpenRead($zipLocation)
            If(($zip.Entries | %{$_.Name}) -contains $kmlInfo.Name){
                $zip.Dispose();
                $trigger = $true
                break;
            }

        }catch{}
        start-sleep -seconds 1
        write-host "." -nonewline
    }
    [IO.Compression.ZipFile]::OpenRead($zipLocation).Dispose()
    Rename-Item -Path $zipLocation -NewName $([System.IO.Path]::ChangeExtension($zipLocation, '.kmz'))
}

kml_to_kmz -kmlPath "C:\Users\Default\Desktop\Test.kml"