2012-08-10 23 views
5

これまでうまく機能していたC#(link)用のStephen ToubのIFileOperationラッパーを使用します。今私はネットワークロケーションから各ネットワークロケーションを独自のサブディレクトリに集めるためにコピーを作成しようとしています。上C:\gather\bar\manageコピー中にIFileOperationを使用してディレクトリを作成する

そしてそうにC:\gather\Foo_data
\\BAR\manage\current

\\FOO\data。問題はFileOperation.CopyItemです。コピー先ディレクトリがまだ存在しないからです。コピー中にIFileOperationが作成されます。私はanother questionから技術を使用して変更ToubのFileOperation.CreateShellItemこれまで:

private static ComReleaser<IShellItem> CreateShellItem(string path) 
{ 
    try 
    { 
     return new ComReleaser<IShellItem>((IShellItem)SHCreateItemFromParsingName(path, null, ref _shellItemGuid)); 
    } 
    catch (FileNotFoundException) 
    { 
     IntPtr pidl = SHSimpleIDListFromPath(path); 
     IShellItem isi = (IShellItem)SHCreateItemFromIDList(pidl, ref _shellItemGuid); 
     Marshal.FreeCoTaskMem(pidl); 
     System.Diagnostics.Debug.WriteLine("Shell item: " + isi.GetDisplayName(SIGDN.DesktopAbsoluteParsing)); 
     return new ComReleaser<IShellItem>(isi); 
    } 
} 

私はそれが働いていることを確認するためにそこにDebug.WriteLineを立ち往生、それが正常に動作しているようです。パスを書き戻します。

しかし、IFileOperation.CopyItemArgumentExceptionを投げ、理由を理解できません。存在しないファイルに対して「IShellItem」を正しく実行していませんか?存在しないディレクトリのIShellItemを作成しようとしているので、SFGAO_FOLDERを取得する必要があると思われます。ではなく、どのようにファイルを作成しますか?

答えて

6

今回の週末(私はワイルドパーティの週末)、多くのグーグルとコーディング実験を経て、解決策を見つけました。

  1. IFileSystemBindDataを実装するCOM互換クラスを作成します。
  2. WIN32_FIND_DATA構造を割り当て、dwFileAttributes = FILE_ATTRIBUTE_DIRECTORYに設定します。 (他のメンバーはここでは無関係ですが、いくつかのテストの後で教えてください)
  3. IFileSystemBindDataクラスのインスタンスを作成します。
  4. WIN32_FIND_DATAオブジェクトをIFileSystemBindData::SetFindDataに渡します。
  5. IBindCtxのインスタンスを作成します。
  6. STR_FILE_SYS_BIND_DATA#definedをL"File System Bind Data"とする)とIFileSystemBindDataオブジェクトを引数に使用して、IBindCtx::RegisterObjectParamと呼び出します。
  7. SHCreateItemFromParsingNameには、作成するディレクトリのパス名と、IBindCtxオブジェクトを指定します。

これは機能します。バインディング・コンテキスト・オブジェクトは、SHCreateItemFromParsingNameにファイルシステムを照会せず、与えられたものだけを使用するように指示します。私はIFileOperationを使って、ファイルを巧みな名前の新しいディレクトリD:\Some\Path\That\Did\Not\Previously\Existにコピーし、7つのディレクトリをすべて作成しました。おそらく、同じテクニックを使って、dwFileAttributesに何を置くかに応じて、存在しないファイルシステムオブジェクトに対してIShellItemを作成することができます。

しかし、それは醜いです。もっと良い方法があることを願っています。私のコーディング実験はC++で行われました。今すぐC#でそれを行うためにCOM interopのものを書く。あるいは、プロジェクトを投げ捨ててC++でやり直す方が簡単かもしれません。

関連する問題