Powershell ZIP CopyHere 抵消异步行为

Powershell ZIP CopyHere counteracting asynchronous behavior

在 Powershell 中,Shell-Application 命名空间的 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"))

这会返回以下错误:

Exception calling "Item" with "1" argument(s): "Not implemented (Exception from HRESULT: 0x80004001 (E_NOTIMPL))" + while($zipPackage.Items().Item($zip.Name) -Eq $null) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ComMethodTargetInvocation

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

我 运行 遇到的问题是试图找到检查 zip 状态的方法。

所以我做了一段时间的触发器,它会触发...如果 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"