C# IFileOperation How to get status and error info

2019-08-19 02:54发布

问题:

I would like to use IFileOperation in my .NET C# application.

I found this article http://blogs.msdn.com/b/msdnmagazine/archive/2007/12/12/6738569.aspx (source code is available here http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/NetMatters2007_12.exe). It is working well so far but I want to get status and error information for all operations.

There is line of code:

if (_callbackSink != null) _sinkCookie = _fileOperation.Advise(_callbackSink);

which should allow me to access this information, but I don't know how to use it.

This is how I call it and I want to get some list of actions with result after fileOp.PerformOperations(); Something like:

File/Folder name | Action | Result 
d:\test\      | Copy | OK
d:\test\a.jpg | Copy | OK
d:\test\b.jpg | Copy | CALCELED

using (FileOperation fileOp = new FileOperation(new FileOperationProgressSink(), this)) {
  fileOp.CopyItem(source, destination, name);
  fileOp.PerformOperations();
}

I know that I can get this information in FileOperationProgressSink.PostCopyItem, but I need them all on FileOperation class so I can access them like fileOp.ResultData[].

Can somebody help me with that?

回答1:

I figured it out.

This is my FileOperationProgressSink class which adds a source file path and a newly created file path to a dictionary in Application.Current.Properties.

using System.Collections.Generic;
using System.Windows;
using PictureManager.ShellStuff.Interfaces;

namespace PictureManager.ShellStuff {
  public class PicFileOperationProgressSink: FileOperationProgressSink {
    public override void PostCopyItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, string pszNewName, uint hrCopy, IShellItem psiNewlyCreated) {
      if (hrCopy != 0) return;
      ((Dictionary<string, string>)Application.Current.Properties["FileOperationResult"]).Add(
        psiItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH), 
        psiNewlyCreated.GetDisplayName(SIGDN.SIGDN_FILESYSPATH));
    }
  }
}

And this is usage of FileOperation

private void CmdTestButton(object sender, ExecutedRoutedEventArgs e) {
  Application.Current.Properties["FileOperationResult"] = new Dictionary<string, string>();
  using (FileOperation fo = new FileOperation(new PicFileOperationProgressSink())) {
    fo.CopyItem(@"d:\!test\003.jpg", @"d:\!test\aaa", "003.jpg");
    fo.PerformOperations();
  }
  var fileOperationResult = (Dictionary<string, string>) Application.Current.Properties["FileOperationResult"];
}

Then I can compare input/output file paths and determinate what happened.