7

Stephen Toub の C# 用 IFileOperation ラッパー (リンク) を使用します。これは今までうまく機能していました。現在、ネットワークの場所からファイルを収集するためにコピーを実行しようとしています。各ネットワークの場所は独自のサブディレクトリです。

\\FOO\dataC:\gather\Foo_data
\\BAR\manage\current_C:\gather\bar\manage

等々。問題は にありFileOperation.CopyItemます。コピー先のディレクトリがまだ存在しないためであるに違いありません — <code>IFileOperation はコピー中に作成しますよね? 別の質問の手法を使用し、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.CopyItemがスローArgumentExceptionされ、その理由がわかりません。IShellItem「存在しないファイルに対して」を正しく行っていませんか?ファイルではなく存在しないディレクトリSFGAO_FOLDERを作成しようとしているので、そこに入る必要があると思いますが、どうすればよいですか?IShellItem

4

1 に答える 1

8

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

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

できます。binding-context オブジェクトはSHCreateItemFromParsingName、ファイルシステムを照会せず、与えられたものだけを使用するように指示します。ファイルを新しい巧妙な名前の directoryにIFileOperationコピーする必要がありD:\Some\Path\That\Did\Not\Previously\Exist、途中で 7 つのディレクトリすべてが作成されました。おそらく、これと同じ手法を使用して、IShellItem存在しないファイルシステム オブジェクトを作成することができますdwFileAttributes

しかし、それは醜いです。もっと良い方法があることを願っています。私のコーディング実験は C++ でした。次に、COM 相互運用機能を記述して、C# で再度実行します。あるいは、プロジェクトを破棄して C++ でやり直す方が簡単かもしれません。

于 2012-08-12T20:53:21.247 に答える