C#中,复制文件的操作十分简单,System.IO.File.Copy()。但是用过的同学都知道,这个方法在复制大文件的时候非常不好用,因为它会阻塞当期线程直到文件复制完毕,要终止也麻烦(把复制操作放到线程中,通过终止线程来终止操作)。如果能使用Explorer中复制文件时的对话框,就能直观的显示复制进度,并且能随时取消复制操作。

要实现Explorer中复制粘贴时的对话框,可以自己编写相关代码,使用异步读写文件字节流的方式来复制文件,这种方式我们今天就不讨论了;

另外一种方法,是使用Windows API SHFileOperation来达到目的;

定义API:

        /// <summary>/// 映射API方法/// </summary>/// <param name="lpFileOp"></param>/// <returns></returns>
[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]private static extern int SHFileOperation(SHFILEOPSTRUCT lpFileOp);/// <summary>/// 多个文件路径的分隔符/// </summary>private const string FILE_SPLITER = "\0";/// <summary>/// Shell文件操作数据类型/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]private class SHFILEOPSTRUCT{public IntPtr hwnd;/// <summary>/// 设置操作方式/// </summary>public wFunc wFunc;/// <summary>/// 源文件路径/// </summary>public string pFrom;/// <summary>/// 目标文件路径/// </summary>public string pTo;/// <summary>/// 允许恢复/// </summary>public FILEOP_FLAGS fFlags;/// <summary>/// 监测有无中止/// </summary>public bool fAnyOperationsAborted;public IntPtr hNameMappings;/// <summary>/// 设置标题/// </summary>public string lpszProgressTitle;}/// <summary>/// 文件操作方式/// </summary>private enum wFunc{/// <summary>/// 移动/// </summary>
FO_MOVE = 0x0001,/// <summary>/// 复制/// </summary>
FO_COPY = 0x0002,/// <summary>/// 删除/// </summary>
FO_DELETE = 0x0003,/// <summary>/// 重命名/// </summary>
FO_RENAME = 0x0004}/// <summary>/// fFlags枚举值,/// 参见:http://msdn.microsoft.com/zh-cn/library/bb759795(v=vs.85).aspx/// </summary>private enum FILEOP_FLAGS{///<summary>///pTo 指定了多个目标文件,而不是单个目录///The pTo member specifies multiple destination files (one for each source file) rather than one directory where all source files are to be deposited.///</summary>
FOF_MULTIDESTFILES = 0x1,///<summary>///不再使用///Not currently used.///</summary>
FOF_CONFIRMMOUSE = 0x2,///<summary>///不显示一个进度对话框///Do not display a progress dialog box.///</summary>
FOF_SILENT = 0x4,///<summary>///碰到有抵触的名字时,自动分配前缀///Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.///</summary>
FOF_RENAMEONCOLLISION = 0x8,///<summary>///不对用户显示提示///Respond with "Yes to All" for any dialog box that is displayed.///</summary>
FOF_NOCONFIRMATION = 0x10,///<summary>///填充 hNameMappings 字段,必须使用 SHFreeNameMappings 释放///If FOF_RENAMEONCOLLISION is specified and any files were renamed, assign a name mapping object containing their old and new names to the hNameMappings member.///</summary>
FOF_WANTMAPPINGHANDLE = 0x20,///<summary>///允许撤销///Preserve Undo information, if possible. If pFrom does not contain fully qualified path and file names, this flag is ignored.///</summary>
FOF_ALLOWUNDO = 0x40,///<summary>///使用 *.* 时, 只对文件操作///Perform the operation on files only if a wildcard file name (*.*) is specified.///</summary>
FOF_FILESONLY = 0x80,///<summary>///简单进度条,意味着不显示文件名。///Display a progress dialog box but do not show the file names.///</summary>
FOF_SIMPLEPROGRESS = 0x100,///<summary>///建新目录时不需要用户确定///Do not confirm the creation of a new directory if the operation requires one to be created.///</summary>
FOF_NOCONFIRMMKDIR = 0x200,///<summary>///不显示出错用户界面///Do not display a user interface if an error occurs.///</summary>
FOF_NOERRORUI = 0x400,///<summary>/// 不复制 NT 文件的安全属性///Do not copy the security attributes of the file.///</summary>
FOF_NOCOPYSECURITYATTRIBS = 0x800,///<summary>/// 不递归目录///Only operate in the local directory. Don't operate recursively into subdirectories.///</summary>
FOF_NORECURSION = 0x1000,///<summary>///Do not move connected files as a group. Only move the specified files.///</summary>
FOF_NO_CONNECTED_ELEMENTS = 0x2000,///<summary>///Send a warning if a file is being destroyed during a delete operation rather than recycled. This flag partially overrides FOF_NOCONFIRMATION.///</summary>
FOF_WANTNUKEWARNING = 0x4000,///<summary>///Treat reparse points as objects, not containers.///</summary>
FOF_NORECURSEREPARSE = 0x8000,}

使用方法:

        public static int Copy(string sourceFiles, string targetFiles){SHFILEOPSTRUCT pm = new SHFILEOPSTRUCT();pm.wFunc = wFunc.FO_COPY;//设置对话框标题,在win7中无效
pm.lpszProgressTitle = "复制文件";pm.pFrom = sourceFiles;pm.pTo = targetFiles;pm.fFlags = FILEOP_FLAGS.FOF_NOCONFIRMATION | FILEOP_FLAGS.FOF_MULTIDESTFILES | FILEOP_FLAGS.FOF_ALLOWUNDO;return SHFileOperation(pm);}

返回值如果为0表示复制成功,非0表示出错,返回值代表意义可参看http://msdn.microsoft.com/zh-cn/library/bb762164(v=vs.85).aspx

这是复制一个文件的,那么如果需要复制多个文件呢?注意上面的pm.pFrom和pm.pTo这两个string属性,传入的字符串可以为多个文件,需要用’\0’作为两个文件路径的分隔符,最后要以’\0\0’(两个)作为结尾,然后还要注意pFrom和pTo文件个数应该一致;(关于使用’\0’分割,一开始我真是想到,试过用分号,逗号,回车符,发现都不行,后来还是看了MSDN才发现应该用’\0’的。)

如果你想要源为文件列表,目标为一个目录,那么,pTo就改成目录,同时要注意pm.fFlags就不要加上FILEOP_FLAGS.FOF_MULTIDESTFILES;

当然,SHFileOperation并不仅仅可以用于复制文件,从上面的wFunc枚举我们可以发现除了复制还有移动、删除、重命名的操作;使用方法也是大同小异。我将其封装于一个类中,并提供多种重载。

原来上传的附件有问题:  ShellFileOperation.rar

请下载这个:ShellFileOperation(修正).rar  我封装的类里面使用到了IEnumerable<T>.Count(),这个需要using System.Linq;当然这个与主功能没关系,如果你使用Framework版本低于3.5,可以将IEnumerable<T>.Count()换成别的实现。感谢二楼“蜗牛往前走”的提示!

转载于:https://www.cnblogs.com/jifengg/archive/2013/05/13/3076131.html

C#中使用SHFileOperation调用Windows的复制文件对话框相关推荐

  1. python文件中的代码调用以及“__init__.py“ 文件说明

    python文件中的代码调用以及"__init__.py" 文件说明 如何调用另一个python文件中的代码 同一文件目录下 不同文件目录下 "__init__.py&q ...

  2. windows系统复制文件到c盘提示0X80070522错误 无法复制文件到系统盘

    windows系统复制文件到c盘提示0X80070522解决方法: 打开powershell 执行 icacls c:\ /setintegritylevel M 命令

  3. windows linux复制文件夹命令,ubuntu下复制目录和文件的指令以及和windows下的copy方式...

    Ubuntu中复制文件或目录的命令 cp(copy)命令 该命令的功能是将给出的文件或目录拷贝到另一文件或目录中. 语法: cp [选项] 源文件或目录 目标文件或目录 说明:该命令把指定的源文件复制 ...

  4. Windows系统复制文件到虚拟机Linux环境的解决

    无法从本地Windows复制大文档到虚拟机Linux环境的解决办法 检测系统本身自带的"open-vm-tools"包:yum list installed | grep open ...

  5. 新手如何解决Windows无法复制文件到VMware下新装UBUNTU的问题?

    1,打开VMware下新装UBUNTU系统,同时按下CTRL+ALT+T组合键,进入Terminal, 2,输入:sudo apt-get autoremove open-vm-tools 然后按回车 ...

  6. [windows][操作系统]复制文件夹到桌面经常到跑左上角导致桌面图标位置错乱

    你有没有遇到过复制文件到桌面时候,明明粘贴在桌面中心,结果跑到左上角去了,而且还会把桌面图标挤乱了.以前一直以为是win10 bug但是系统更新后一直有这个毛病,为了解决这个问题终于找到答案 Win1 ...

  7. windows api打开文件对话框

    用windows api 写打开文件对话框主要使用OPENFILENAME ,GetOpenFileName, GetSaveFileName; 1.OPENFILENAME 结构体介绍:要使用Get ...

  8. 按住ctrl键多选_解决烦恼:按住Ctrl键单击选择时,阻止Windows意外复制文件

    按住ctrl键多选 Have you ever tried to select a bunch of files in Windows Explorer while holding down the ...

  9. Windows批量复制文件copy命令bat批处理文件

    如果需要复制很多文件,手动肯定是累死人的. 我们可以使用后缀为.bat的批处理文件,双击运行. 自己写一个.bat就好了 import jsonwith open('long_answer_examp ...

  10. C#中调用Windows API的要点

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...

最新文章

  1. Springboot+Mybatis+Durid
  2. java ssh框架 struts spring hibernate 简介
  3. jQuery应用实例2:简单动画
  4. Taro+react开发(31)同样的数据可以数组遍历
  5. jmu-python-函数-找钱_python函数题 - osc_wv1mxwu2的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. 从一次线上故障思考Java问题定位思路
  7. VS中warning MSB8012:TargetPath与 Linker 的 OutputFile 属性值不匹配
  8. angular 2+ innerHTML属性中内联样式丢失
  9. 装机之必备软件下载合集
  10. 基于遗传算法的TSP和MTSP问题求解(python)
  11. 【定位原理揭秘第三期】室内定位技术原理揭秘
  12. 有关计算机的英语诗歌带翻译,经典的著名英语短诗歌带翻译
  13. 端口扫描神器 - Nmap的基本使用
  14. Python Qt GUI设计:菜单栏、工具栏和状态栏的使用方法(拓展篇—2)
  15. Linux安装jdk
  16. 微软输入法的使用技巧
  17. css3 乌云散去,纯css实现乌云密布的天气图标效果
  18. paypay+thinkphp开发接入网站
  19. SVM转化为对偶问题求解的原因
  20. ForexClub:卡塔尔豪掷千亿举办世界杯,钱哪儿来的?

热门文章

  1. java打包文件生成zip压缩包
  2. RPC调用方如何实现异步调用:CompletableFuture
  3. MAML++:HOW TO TRAIN YOUR MAML论文精读
  4. matlab 加权回归估计_Matlab:地理加权回归基本操作
  5. 非负矩阵分解(NMF)
  6. *揭秘!阅读类APP如何实现自动阅读赚钱**
  7. 短视频源码下载、vue+html+elementui短视频播放实现,web、pc静态页短视频、手机网页版短视频
  8. 如何从CPU顶盖获取有用信息
  9. 常见音频格式大盘点分析
  10. canvas系列 — canvas常用API介绍