使用IFileOperation一个复制过程中创建的目录(Creating directories

2019-07-30 21:51发布

使用斯蒂芬Toub的IFileOperation包装为C#( 链接 ),它一直很好,直到如今。 现在我试图做一个副本从网络位置,每个网络位置到它自己的子目录中收集的文件。

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

等等。 问题出在FileOperation.CopyItem 。 它必须是因为目标目录不存在yet- 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为不存在的 ,而不是文件,而是如何?

Answer 1:

很多谷歌搜索和编码实验本周末(什么是狂野派对周末)后,我找到了解决办法。

  1. 编写实现COM兼容类IFileSystemBindData
  2. 分配一个WIN32_FIND_DATA结构,并设置其dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY 。 (其他成员是这里无关紧要,因为据我的一些测试后告诉。)
  3. 创建的实例IFileSystemBindData类。
  4. 通过你的WIN32_FIND_DATA对象IFileSystemBindData::SetFindData
  5. 创建的实例IBindCtx
  6. 调用其IBindCtx::RegisterObjectParam用的参数STR_FILE_SYS_BIND_DATA#define d为L"File System Bind Data" )和您IFileSystemBindData对象。
  7. 呼叫SHCreateItemFromParsingName与目录的路径名来创建,和你的IBindCtx对象。

有用。 结合上下文对象告诉SHCreateItemFromParsingName没有查询的文件系统,并且只使用它给了。 我IFileOperation将文件复制到新的和巧妙地命名的目录D:\Some\Path\That\Did\Not\Previously\Exist ,它创造了沿途所有七个目录。 据推测,这同样的技术可以用来创建IShellItem任何不存在的文件系统对象,这取决于你把什么dwFileAttributes

但它的丑陋。 我希望有一个更好的办法。 我的编码实验是用C ++; 现在写的COM互操作的东西在C#中做一遍。 或者,也许它会更容易抛出了项目,并在C ++中开始。



文章来源: Creating directories during a copy using IFileOperation
标签: c# com