您的位置:首页 > 其它

文件夹拷贝,判断,生成当前用户权限的文件夹

2017-09-23 11:07 453 查看
使用到的API:

CreateDirectory:创建目录

FindFirstFile,FindNextFile 查找文件

RemoveDirectory:删除空目录

GetFileAttributes:获取文件属性

CreateSymbolicLink:创建符号链接

GetDriveType:获取盘符

SHFileOperation:拷贝文件

拷贝文件夹有两种方案,一种是通过SHFileOperation来拷贝,代码简洁,只需要填写SHFILEOPSTRUCT的参数就可以。另一种是用FindFirstFile,FindNextFile 查找文件递归去复制。

方法一

BOOL CopyFolder(LPTSTR pFrom, LPTSTR pTo)
{
SHFILEOPSTRUCT FileOp={0};
ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION| //不出现确认对话框
FOF_NOCONFIRMMKDIR ; //需要时直接创建一个文件夹,不需用户确定
//FileOp.fFlags = FOF_NO_UI;
FileOp.pFrom = pFrom;
FileOp.pTo = pTo;
FileOp.wFunc = FO_COPY;
if( SHFileOperation(&FileOp) == 0){
cout<<" copy file success!!!"<<endl;
return TRUE;
}else{
cout<<"copy file failed!!!  "<<endl;
return FALSE;
}
}


注意:当我尝试隐藏所有弹框(确认框,进度条,冲突选项等)FileOp.fFlags = FOF_NO_UI时。在拷贝较大的文件夹时会报错,返回值是32(进程无法访问文件,因为另一个程序正在使用此文件),用上面的参数就会弹出进度条,就不会报错。

方法二:

通过FindFirstFile,FindNextFile 递归查找文件,用copyfile复制文件,不会存在方法一的问题,还能拷贝隐藏文件,CreateDirectory创建头目录时,可以设置属性为只有当前用户可以访问。

BOOL CopyDir(LPTSTR pszSrcPath,LPTSTR pszDstPath)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
TCHAR tmpsrc[256];
_tcscpy(tmpsrc,pszSrcPath);
_tcscat(tmpsrc,L"\\*.*");
hFind = FindFirstFile(tmpsrc, &FindFileData);
if(hFind == INVALID_HANDLE_VALUE)
return FALSE;
CreateDirectory(pszDstPath,NULL);

do
{
TCHAR newdst[256];
_tcscpy(newdst,pszDstPath);
if(newdst[_tcslen(newdst)]!='\\')
_tcscat(newdst,L"\\");
_tcscat(newdst,FindFileData.cFileName);

TCHAR newsrc[256];
_tcscpy(newsrc,pszSrcPath);
if(newsrc[_tcslen(newsrc)]!='\\')
_tcscat(newsrc,L"\\");

_tcscat(newsrc,FindFileData.cFileName);
if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY){
if(_tcscmp(FindFileData.cFileName,L".")!=0&&_tcscmp(FindFileData.cFileName,L"..")!=0)
CopyDir(newsrc,newdst);
}else
CopyFile(newsrc,newdst,TRUE);

}while(FindNextFile(hFind,&FindFileData));
FindClose(hFind);
return TRUE;
}


判断是否文件夹,通过GetFileAttributes获取文件属性,文件夹是FILE_ATTRIBUTE_DIRECTORY属性,可能会是隐藏文件夹FILE_ATTRIBUTE_HIDDEN

BOOL IsDirectory(LPTSTR lpDirPath)
{
DWORD dwRes = GetFileAttributes(lpDirPath);
if(dwRes == INVALID_FILE_ATTRIBUTES){
cout<<"GetFileAttributes failed"<<endl;
return FALSE;
}

if( dwRes == (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY )
|| dwRes == FILE_ATTRIBUTE_DIRECTORY )
return TRUE;
return FALSE;
}


创建只有当前用户有访问权限的文件夹

原理:获取当前用户名,通过LookupAccountName用户的psid,再通过AddAccessAllowedAce获取pacl,用SetSecurityDescriptorDacl设置SECURITY_DESCRIPTOR,最后配置SECURITY_ATTRIBUTES

BOOL IsDirExist(LPTSTR pszDir)
{
DWORD dwAttrib = GetFileAttributes(pszDir);
return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

BOOL CreateDir(LPTSTR pszDirName)
{
if(IsDirExist(pszDirName))
return FALSE;

SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;

BYTE aclBuffer[1024];
PACL pacl = (PACL)&aclBuffer;

BYTE sidBuffer[100];
PSID psid = (PSID)&sidBuffer;
DWORD sidBufferSize = 100;
TCHAR domainBuffer[80];
DWORD domainBufferSize = 80;
SID_NAME_USE snu;

DWORD dwBufferSize = 100;
TCHAR UserName[100];

GetUserName(UserName,&dwBufferSize);

InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);

InitializeAcl(pacl,1024,ACL_REVISION);
LookupAccountName(0,UserName,psid,&sidBufferSize,domainBuffer,&domainBufferSize,&snu);
AddAccessAllowedAce(pacl,ACL_REVISION,GENERIC_ALL,psid);
SetSecurityDescriptorDacl(&sd,TRUE,pacl,FALSE);

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;

CreateDirectory(pszDirName,&sa);
return TRUE;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: