SHFileOperation 这个API函数怎么用起来结果飘忽不定?

starytx 2014-01-10 06:13:08
环境:vs2005.我的一个复制文件夹的函数如下:
// 将原路径srcDir中的文件/文件夹(不包括srcDir本身),拷贝到目标路径desDir下,存在的话覆盖
bool copyForder(const char * srcDir,const char *desDir)
{
SHFILEOPSTRUCT fop;
ZeroMemory(&fop, sizeof(fop));
fop.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR |FOF_MULTIDESTFILES;
fop.wFunc = FO_COPY;
fop.pFrom = _T(srcDir);
fop.pTo = _T(desDir);

int nResult = SHFileOperation(&fop);
if(0 == nResult)
{
return true;
}

return false;
}

测试代码如下:
	string src="D:\\source\\";
string des = "D:\\dest\\aaa\\";
if(!copyForder(src.c_str() ,des.c_str()))
printf("文件夹拷贝失败!\n");
else
printf("文件夹拷贝成功!\n");
好像文件夹路径最后加不加那个斜杠会影响结果?之前试的时候从source往dest中复制的话怎么折腾都成功,现在往dest下的aaa文件夹里放感觉有时候就会失败,nResult返回值有时候是123,有时候是87,有墙,还查不到更多的信息,有时候复制成功但是又吧source本身都复制过去了,好混乱啊,到底怎么正确使用呢?
...全文
464 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
starytx 2014-01-11
  • 打赏
  • 举报
回复
这函数真不好用,运行的时候一会儿失败一会儿成功的,哎,还是递归复制算了。
vipcxj 2014-01-10
  • 打赏
  • 举报
回复
引用 5 楼 starytx 的回复:
[quote=引用 2 楼 vipcxj 的回复:] Important You must ensure that the source and destination paths are double-null terminated. A normal string ends in just a single null character. If you pass that value in either the source or destination members, the function will not realize when it has reached the end of the string and will continue to read on in memory until it comes to a random double null value. This can at least lead to a buffer overrun, and possibly the unintended deletion of unrelated data. 如果非要说LZ有啥问题,你的源路径和目标路径都必须是双null结尾,因为这个API支持多个路径放一起,用null隔开,所以双null才是标志路径结束。 example

// WRONG
LPTSTR pszSource = L"C:\\Windows\\*";

// RIGHT
LPTSTR pszSource = L"C:\\Windows\\*\0";
我看过网上说的,末尾也加上"\0\0"了,还是不稳定[/quote] 应该是多一个"\0",因为字符串本身就有一个"\0",不过感觉这貌似不是问题,LZ可以试试把FOF_NOERRORUI这个flag去掉,看看错误到底是啥~ 还有我上面给的示例代码就是msdn提供的,或许它就是不支持末尾是"\\"的,你干脆再弄个函数,一旦末尾源路径末尾是"\\",你就改成"\\*\0",这应该不难吧~
starytx 2014-01-10
  • 打赏
  • 举报
回复
引用 2 楼 vipcxj 的回复:
Important You must ensure that the source and destination paths are double-null terminated. A normal string ends in just a single null character. If you pass that value in either the source or destination members, the function will not realize when it has reached the end of the string and will continue to read on in memory until it comes to a random double null value. This can at least lead to a buffer overrun, and possibly the unintended deletion of unrelated data. 如果非要说LZ有啥问题,你的源路径和目标路径都必须是双null结尾,因为这个API支持多个路径放一起,用null隔开,所以双null才是标志路径结束。 example

// WRONG
LPTSTR pszSource = L"C:\\Windows\\*";

// RIGHT
LPTSTR pszSource = L"C:\\Windows\\*\0";
我看过网上说的,末尾也加上"\0\0"了,还是不稳定
vipcxj 2014-01-10
  • 打赏
  • 举报
回复
引用 3 楼 starytx 的回复:
[quote=引用 1 楼 vipcxj 的回复:] http://msdn.microsoft.com/en-us/library/windows/desktop/bb775771(v=vs.85).aspx 微软更推荐用IFileOperation
怎么用啊?比较紧急啊,没有多少时间来自己研究了,或者有其他好用的赋值文件夹的代码也可以。xcopy命令行的就算了,现有的就是这个,用其他的来替换的。[/quote] 我刚刚又看了下IFileOperation要求windows最低版本wista,实在有点坑,LZ,你试试我说的在字符串结尾在加个"\0"吧,这是msdn说滴 其实copy文件,boost提供了一个跨平台的支持,就是FileSystem库,不过这个库是需要编译的。用法和Java里的File类很像,并且提供文件拷贝,复制,删除等等操作~
starytx 2014-01-10
  • 打赏
  • 举报
回复
引用 1 楼 vipcxj 的回复:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775771(v=vs.85).aspx 微软更推荐用IFileOperation
怎么用啊?比较紧急啊,没有多少时间来自己研究了,或者有其他好用的赋值文件夹的代码也可以。xcopy命令行的就算了,现有的就是这个,用其他的来替换的。
vipcxj 2014-01-10
  • 打赏
  • 举报
回复
Important You must ensure that the source and destination paths are double-null terminated. A normal string ends in just a single null character. If you pass that value in either the source or destination members, the function will not realize when it has reached the end of the string and will continue to read on in memory until it comes to a random double null value. This can at least lead to a buffer overrun, and possibly the unintended deletion of unrelated data. 如果非要说LZ有啥问题,你的源路径和目标路径都必须是双null结尾,因为这个API支持多个路径放一起,用null隔开,所以双null才是标志路径结束。 example

// WRONG
LPTSTR pszSource = L"C:\\Windows\\*";

// RIGHT
LPTSTR pszSource = L"C:\\Windows\\*\0";
vipcxj 2014-01-10
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775771(v=vs.85).aspx 微软更推荐用IFileOperation
API功能详解: 使用API函数SHFileOperation,这个函数可以同时拷贝、删除、改名或移动多个文件,甚至整个目录。如果你愿意,还可以显示相应的动画对话框,功能十分强大。SHFileOperation的参数是一个SHFILEOPSSTRUCT结构。这个结构中各成员的含义如下: - hwnd - 显示文件操作对话框的窗口句柄 - wFunc - 表示要进行的操作,可以取以下值: - FO_COPY - 拷贝文件。所要拷贝的文件由pFrom成员指定,目的地址有pTo成员指定。 - FO_DELETE - 删除pFrom指定的文件。(pTo 被忽略。) - FO_MOVE - 移动文件。所要移动的文件由pFrom成员指定,目的地址有pTo成员指定。 - FO_RENAME - 改名pFrom指定的文件。 - pFrom - 指定文件名的缓冲区的地址。必须以Chr(0)结尾。如果包括多个文件以Chr(0)分割。 - pTo - 指定目的文件名或目录的缓冲区的地址。必须以Chr(0)结尾。如果使用了FOF_MULTIDESTFILES标志,可以包括多个文件名,文件名之间以Chr(0)分割。 - fFlags - 标志: - FOF_ALLOWUNDO - 允许恢复 - FOF_FILESONLY - 如果使用了*.*,只操作文件。 - FOF_MULTIDESTFILES - pTo成员可以为多个目的文件。 - FOF_NOCONFIRMATION - 不显示确认对话框。 - FOF_NOCONFIRMMKDIR - 不确认是否建立目录。 - FOF_NOERRORUI - 如果有错误,不显示用户界面。 - FOF_RENAMEONCOLLISION - 如果目的文件已经存在,给要处理的文件一个新名字。 - FOF_SILENT - 不显示进度对话框。 - FOF_SIMPLEPROGRESS - 显示进度框,但不显示文件名。 - fAnyOperationsAborted -如果用户退出,该成员为TRUE,否则为FALSE。 - lpszProgressTitle - 进度框的标题,只有选择了FOF_SIMPLEPROGRESS标志才有效。

65,182

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧