|
这是网上找的一段代码,但是在删除目录时总是说无法读取源文件或磁盘。但是目录确实存在。
查了查MSDN,网上看到别人也有同样的问题,看看他们的解答。原来SHFileOperation中的pFrom可以表示多个路径,各个路径之间以'\0'分隔,最后以'\0\0'(即连续的两个'\0')结束,
于是改了过来。可是还是不行。
去掉路径最后的一个'\'("c:\\data\\"改为"c:\\data"),成功。
下面这个函数需要注意同样的问题。
BOOL CUsbCtrl::CopyFolder(CString lpszFromPath,CString lpszToPath)
{
lpszFromPath += '\0';
lpszToPath += '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION ;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = lpszFromPath;
FileOp.pTo = lpszToPath;
FileOp.wFunc = FO_COPY;
return SHFileOperation(&FileOp) == 0;
}
其他
1 int SHFileOperation( LPSHFILEOPSTRUCT lpFileOp);
如果执行成功返回0.
1 typedef struct _SHFILEOPSTRUCT { 2 HWND hwnd;//指向发送消息的窗口 3 UINT wFunc;//执行的操作 4 LPCTSTR pFrom;//源文件名 5 LPCTSTR pTo;//目标文件名 6 FILEOP_FLAGS fFlags;//操作与确认标识 7 BOOL fAnyOperationsAborted;//操作是否终止 8 LPVOID hNameMappings;//文件映射 9 LPCTSTR lpszProgressTitle;//进度条标题 10 } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;
参数说明:
wFunc:要执行的操作
1.FO_COPY:复制 2.FO_DELETE:删除 3.FO_MOVE:移动 4.FO_RENAME:重命名
pFrom:源文件名
MSDN上说要以两个\0结束,所以一般的字符串必须还要加上一个\0
比如:
1 // 错误的用法 2 LPTSTR pszSource = L"C:\\Windows"; 3 4 // 正确的用法 5 LPTSTR pszSource = L"C:\\Windows\0";
对于CString,正确的用法是这样的
1 CString strSource("C:\\Windows"); 2 3 strSource += '\0';//注意必须是'\0'而不是"\0"!~!!
fFlags:执行标识
1 FOF_SILENT //不产生正在复制的对话框 2 FOF_NOCONFIRMMKDIR//如果目的目录不存在,就默认创建 3 FOF_NOCONFIRMATION //不出现确认文件替换对话框(默认替换原来的文i件) 4 FOF_NOERRORUI//不出现错误对话框
注:最好不要同时使用FOF_NOERRORUI,FOF_NOCONFIRMMKDIR,因为FOF_NOCONFIRMMKDIR屏蔽了missing directory Error,但FOF_NOERROR又屏蔽了missing directory Error,那么在同时使用FOF_NOERRORUI,FOF_NOCONFIRMMKDIR时也阻止了新目录安静(没有用户确认要产生新目录的对话框)的产生!!那么如何同时使用FOF_NOERRORUI,FOF_NOCONFIRMMKDIR?
就必须先确认pTo所指定的目录存在即可
1 BOOL MakeSureDiretoryPathExists(LPCSTR DirPath); //使用它要包含imagehlp.h和imagehlp.lib
如何判断同时存在FOF_NOERRORUI,FOF_NOCONFIRMMKDIR
=====
如果出现弹出"无法删除 文件无法:读取源文件或磁盘文.",可:FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI
=====
1 FOF_RENAMEONCOLLISION//有重复文件时自动重命名 2 3 FOF_ALLOWUNDO //将文件放入回收站,否则直接删除,一般这个最好做默认
使用该函数进行文件拷贝、移动或删除时,如果需要的时间很长,则程序会自动在进行的过程中出现一个无模式的对话框(Windows操作系统提供的文件操作对话框),用来显示执行的进度和执行的时间,以及正在拷贝、移动或删除的文件名,此时结构中的成员lpszProgressTitle显示此对话框的标题。fFlags是在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其组合:
1 FOF_FILESONLY:执行通配符,只执行文件; 2 3 FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢复文件;
1 FOF_NOCONFIRMATION:在出现目标文件已存在的时候,如果不设置此项,则它会出现确认是否覆盖的对话框,设置此项则自动确认,进行覆盖,不出现对话框。 2 3 FOF_NOERRORUI:设置此项后,当文件处理过程中出现错误时,不出现错误提示,否则会进行错误提示。 4 5 FOF_RENAMEONCOLLISION:当已存在文件名时,对其进行更换文提示。 6 7 FOF_SILENT:不显示进度对话框。 8 9 FOF_WANTMAPPINGHANDLE:要求SHFileOperation()函数返回正处于操作状态的实际文件列表,文件列表名柄保存在hNameMappings成员中。 SHFILEOPSTRUCT结构还包含一个SHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每个处于操作状态的文件的新旧路径。
在使用该函数删除文件时必须设置SHFILEOPSTRUCT结构中的神秘FOF_ALLOWUNDO标志,这样才能将待删除的文件拷到Recycle Bin,从而使用户可以撤销删除操作。需要注意的是,如果pFrom设置为某个文件名,用FO_DELETE标志删除这个文件并不会将它移到Recycle Bin,甚至设置FOF_ALLOWUNDO标志也不行,在这里你必须使用全路径名,这样SHFileOperation才会将删除的文件移到Recycle Bin。
例子:
1 CString strSrc("D:\\test1"); 2 CString strDes("D:\\test2"); 3 strSrc += '\0';//必须加'\0' 4 strDes += '\0'; 5 SHFILEOPSTRUCT FileOp; 6 FileOp.fFlags = FOF_ALLOWUNDO|FOF_MULTIDESTFILES|FOF_SIMPLEPROGRESS;// 7 CString str("正在进行中"); 8 str += '\0'; 9 FileOp.lpszProgressTitle = str; 10 FileOp.hwnd =m_hWnd; 11 FileOp.hNameMappings = NULL; 12 FileOp.pFrom = strSrc; // 13 FileOp.pTo = strDes; 14 FileOp.wFunc = FO_COPY; 15 16 BOOL bOk; 17 bOk = SHFileOperation(&FileOp); 18 if (!FileOp.fAnyOperationsAborted)//终止 19 { 20 if(bOk) 21 MessageBox(_T("操作出现错误!")); 22 else 23 MessageBox(_T("操作完成!")); 24 } 25 else 26 { 27 MessageBox(_T("操作已终止!"); 28 }
今天看到一个关于SHFileOperation函数使用的介绍,发现下面一些有用的资料,都是些之前未仔细了解的方面,这里把他们记录下来,留待以后查阅参考。fFlags成员标志间的关系
标志 | 抑制的对话框 | 相关性与优先级 |
FOF_MULTIDESTFILES | 无 | 无 |
FOF_FILESONLY | 无 | 无 |
FOF_SILENT | 如果设置,进度对话框不显示。 | 优先于FOF_SIMPLEPROGRESS标志。 |
FOF_SIMPLEPROGRESS | 无 | 为FOF_SILENT标志所抑制。 |
FOF_RENAMEONCOLLISION | 如果设置了这个标志,当被移动或拷贝的文件与已存在文件同名时置换对话框不会出现。 | 名字冲突时,如果FOF_NOCONFIRMATION标志设置,则操作继续。 如果二者都设置了,则它优先于FOF_NOCONFIRMATION。即,文件以给定的新名字复制,而不是覆盖。 |
FOF_NOCONFIRMATION | 如果设置,确认对话框在任何情况下都不出现。 | 名字冲突时,引起文件覆盖,除非设置了FOF_RENAMEONCOLLISION标志。 |
FOF_NOCONFIRMMKDIR | 抑制请求建立新文件夹的对话框 | 缺省目录作为严重错误产生一个错误消息框。 建立目录的确认对话框作为错误消息框是否显示依赖于FOF_NOERRORUI的设置。 |
FOF_NOERRORUI | 抑制所有错误消息框。 | 优先于前一个标志。如果设置,则,缺省目录引起不被处理的异常,并且返回错误码。 |
删除文件
文件删除是一个简单的操作,它仅仅影响到输入缓冲pFrom,而pTo缓冲被忽略。与文件复制一样,操作的详细情况依赖于标志的设置。相关的标志是:
标志 | 值 | 描述 |
FOF_SILENT | 0x0004 | 这个操作不回馈给用户,就是说,不显示进度对话框。相关的消息框仍然显示。 |
FOF_NOCONFIRMATION | 0x0010 | 这个标志使函数对任何遇到的消息框都自动回答Yes。 |
FOF_ALLOWUNDO | 0x0040 | 如果设置,这个标志强迫函数移动被删除的文件到‘回收站’中。否则,文件将被物理地从磁盘上删除。 |
FOF_FILESONLY | 0x0080 | 设置这个标志导致函数仅仅删除文件,跳过目录项。它仅仅应用于指定通配符的情况。 |
FOF_SIMPLEPROGRESS | 0x0100 | 这导致简化用户界面。使之只有动画而不报告被删除的文件名。代之的是显示lpszProgressTitle成员中指定的文字。(Win7实际中貌似不可用) |
FOF_NOERRORUI | 0x0400 | 如果设置了这个标志,任何发生的错误都不能使消息框显示,而是程序中返回错误码。 |
这里出现的标志最要紧的是FOF_ALLOWUNDO,它决定文件是否一次就全部删除,或存储到‘回收站’中等候可能的恢复。如果FOF_ALLOWUNDO被设置,文件则被移动到回收站,并且这个操作可以被Undo(尽管可以手动Undo)。Undo特征仅在删除下可用,在拷贝与移动中没有等价的操作。
SHFileOperation()函数的返回值
MSDN资料中说明,SHFileOperation()在成功时返回0,失败时返回非0值。显然这是真的,但并不是最有用的解释。重复测试这个函数,可以确信它有非常多的终止方式。事实上,我们经常在系统错误的提示中运行,在有些地方这个函数只是简单地返回从更靠近文件系统的其它程序中获得的返回码。下面列表给出了SHFileOperation()返回的最通常的部分错误。
错误码 | 描述 |
2 | 如果你试图重命名多重文件,这个消息就会出现。描述是相当直接的:系统不能找到指定的文件。 |
7 | 在询问是否想要置换给定文件时,你回答了‘取消’,函数就返回这个错误码。它的描述也是相当的不明确—存储控制块被销毁。 |
115 | 在试图重命名文件到不同的文件夹时,发生这个文件系统错。重命名文件只是改变文件名,而不能改变文件夹。 |
117 | 一个IOCTL错(输入/输出控制),在目的路径中有错误时或取消了新目录的建立时,这个错误发生了。 |
123 | 你正在试图重命名一个文件,然而你给出的名字是一个已经存在的文件。它也有一个无用的描述:文件名,目录名,或卷标号的语法是不正确的。 |
1026
| 在试图移动或拷贝一个不存在的文件时,出现这个文件系统错。一般地,它提示了,源缓冲中的某些东西应该修改一下。这个错误码弹出一个的错误框,你可以通过设置FOF_NOERRORUI标志抑制它的显示。 |