2017-12-15 97 views
0

Powershell内で、Shell-Application名前空間のCopyHereメソッドは非同期です。私の主な目標は、KMLファイルをKMZファイルに変換することです。これを行うプロセスは、同じ名前のZIPファイルを作成し、KMLをKMZにコピーし(ファイルを圧縮する)、ZIPの名前をKMZに変更します。残念なことに、非同期とは、CopyHereメソッドが完了する前に名前変更関数が呼び出されていることを意味します。私はこれを解決する多くの例を見出しました。私が見つけた最もきれいな1は以下の通りです:Powershell ZIP 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メソッドを悪用だろうか?私は混乱しています。なぜなら、「きれいに」現れるものが機能していないからです。私もHereを提供しているコードのスニペットを試みました。この特定の状況で.Itemメソッドについても不平を言っています。

答えて

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" 
+0

これは実際には完全に機能しました。私は新しい項目のインスタンス化に "-ItemType file"を追加する必要がありましたが、それは速い修正でした(そうでなければ、タイプを入力するよう促していました)。私は、ISEの出力が一連のグローバル設定(CodeBase、FullName、EntryPoint、DefinedTypesなど40種類)を吐き出していることに気付きました。コードのどの部分がその出力を吐き出しているのかわかりませんが、間違いなく混乱しています。何か案は? –

+0

'[Reflection.Assembly] :: LoadWithPartialName(' System.IO.Compression.FileSystem ')'行は、アセンブリパラメータの詳細な出力をコンソールにダンプします。私は、 '| Out-Null 'を入力して出力をマスクします。すべてが完全にまだ動作しています。 –

+0

うれしいあなたのために働いて:) – ArcSet

関連する問題