C#中使用SHFileOperation调用Windows的复制文件对话框
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的复制文件对话框相关推荐
- python文件中的代码调用以及“__init__.py“ 文件说明
python文件中的代码调用以及"__init__.py" 文件说明 如何调用另一个python文件中的代码 同一文件目录下 不同文件目录下 "__init__.py&q ...
- windows系统复制文件到c盘提示0X80070522错误 无法复制文件到系统盘
windows系统复制文件到c盘提示0X80070522解决方法: 打开powershell 执行 icacls c:\ /setintegritylevel M 命令
- windows linux复制文件夹命令,ubuntu下复制目录和文件的指令以及和windows下的copy方式...
Ubuntu中复制文件或目录的命令 cp(copy)命令 该命令的功能是将给出的文件或目录拷贝到另一文件或目录中. 语法: cp [选项] 源文件或目录 目标文件或目录 说明:该命令把指定的源文件复制 ...
- Windows系统复制文件到虚拟机Linux环境的解决
无法从本地Windows复制大文档到虚拟机Linux环境的解决办法 检测系统本身自带的"open-vm-tools"包:yum list installed | grep open ...
- 新手如何解决Windows无法复制文件到VMware下新装UBUNTU的问题?
1,打开VMware下新装UBUNTU系统,同时按下CTRL+ALT+T组合键,进入Terminal, 2,输入:sudo apt-get autoremove open-vm-tools 然后按回车 ...
- [windows][操作系统]复制文件夹到桌面经常到跑左上角导致桌面图标位置错乱
你有没有遇到过复制文件到桌面时候,明明粘贴在桌面中心,结果跑到左上角去了,而且还会把桌面图标挤乱了.以前一直以为是win10 bug但是系统更新后一直有这个毛病,为了解决这个问题终于找到答案 Win1 ...
- windows api打开文件对话框
用windows api 写打开文件对话框主要使用OPENFILENAME ,GetOpenFileName, GetSaveFileName; 1.OPENFILENAME 结构体介绍:要使用Get ...
- 按住ctrl键多选_解决烦恼:按住Ctrl键单击选择时,阻止Windows意外复制文件
按住ctrl键多选 Have you ever tried to select a bunch of files in Windows Explorer while holding down the ...
- Windows批量复制文件copy命令bat批处理文件
如果需要复制很多文件,手动肯定是累死人的. 我们可以使用后缀为.bat的批处理文件,双击运行. 自己写一个.bat就好了 import jsonwith open('long_answer_examp ...
- C#中调用Windows API的要点
在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...
最新文章
- Springboot+Mybatis+Durid
- java ssh框架 struts spring hibernate 简介
- jQuery应用实例2:简单动画
- Taro+react开发(31)同样的数据可以数组遍历
- jmu-python-函数-找钱_python函数题 - osc_wv1mxwu2的个人空间 - OSCHINA - 中文开源技术交流社区...
- 从一次线上故障思考Java问题定位思路
- VS中warning MSB8012:TargetPath与 Linker 的 OutputFile 属性值不匹配
- angular 2+ innerHTML属性中内联样式丢失
- 装机之必备软件下载合集
- 基于遗传算法的TSP和MTSP问题求解(python)
- 【定位原理揭秘第三期】室内定位技术原理揭秘
- 有关计算机的英语诗歌带翻译,经典的著名英语短诗歌带翻译
- 端口扫描神器 - Nmap的基本使用
- Python Qt GUI设计:菜单栏、工具栏和状态栏的使用方法(拓展篇—2)
- Linux安装jdk
- 微软输入法的使用技巧
- css3 乌云散去,纯css实现乌云密布的天气图标效果
- paypay+thinkphp开发接入网站
- SVM转化为对偶问题求解的原因
- ForexClub:卡塔尔豪掷千亿举办世界杯,钱哪儿来的?
热门文章
- java打包文件生成zip压缩包
- RPC调用方如何实现异步调用:CompletableFuture
- MAML++:HOW TO TRAIN YOUR MAML论文精读
- matlab 加权回归估计_Matlab:地理加权回归基本操作
- 非负矩阵分解(NMF)
- *揭秘!阅读类APP如何实现自动阅读赚钱**
- 短视频源码下载、vue+html+elementui短视频播放实现,web、pc静态页短视频、手机网页版短视频
- 如何从CPU顶盖获取有用信息
- 常见音频格式大盘点分析
- canvas系列 — canvas常用API介绍