CPathUtils.h
#pragma once
#include <wtypesbase.h>
#include <tchar.h>
#include <string>
#include <vector>
#include <map>
#include <functional>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
namespace CPathUtils
{
typedef struct _FILEINFO
{
_tstring m_filePath;
unsigned long long m_fileSize;
DWORD m_fileAttributes;
unsigned long long m_ftCreationTime;
unsigned long long m_ftLastAccessTime;
unsigned long long m_ftLastWriteTime;
_FILEINFO() :
m_fileSize(0),
m_fileAttributes(0),
m_ftCreationTime(0),
m_ftLastAccessTime(0),
m_ftLastWriteTime(0)
{
};
}FILEINFO;
//
// @brief: 获取当前进程完全路径
// @ret: 当前进程完全路径 如 D:\Software\HxDPortableSetup.exe
_tstring GetCurrentModulePath();
//
// @brief: 获取当前进程所在目录
// @ret: 当前进程所在目录 如 D:\Software
_tstring GetCurrentModuleDir();
//
// @brief: 获取当前进程名
// @ret: 当前进程名 如 HxDPortableSetup.exe
_tstring GetCurrentModuleName(bool bHasExt = false);
//
// @brief: 获取文件所在驱动器
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 文件夹 如 D:
_tstring GetFileDriver(const _tstring& strPath);
//
// @brief: 获取文件所在文件夹
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 文件夹 如 D:\Software
_tstring GetFileDir(const _tstring& strPath);
//
// @brief: 获取文件名
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @param: bHasExt 是否包含扩展名
// @ret: 文件夹 如 HxDPortableSetup
_tstring GetFileName(const _tstring& strPath, bool bHasExt = false);
//
// @brief: 获取文件扩展名
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @param: bHasDot 是否包含点号
// @ret: 文件夹 如 exe
_tstring GetFileExt(const _tstring& strPath, bool bHasDot = false);
//
// @brief: 获取短路径
// @param: strPath 输入长路径(必须存在)
// @ret: 短路径
_tstring GetShortPath(const _tstring& strPath);
//
// @brief: 获取长路径
// @param: strPath 输入短路径(必须存在)
// @ret: 长路径
_tstring GetLongPath(const _tstring& strPath);
//
// @brief: 获取全路径
// @param: strPath 输入路径
// @ret: 全路径
_tstring GetFullPath(const _tstring& strPath);
//
// @brief: DOS路径转Nt路径
// @param: strPath 路径
// @ret: _tstring Win32 样式的 NT 路径
_tstring DosPathToNtPath(const _tstring& strPath);
//
// @brief: Nt路径转DOS路径
// @param: strPath 路径
// @ret: _tstring DOS路径
_tstring NtPathToDosPath(const _tstring& strPath);
//
// @brief: 获取路径属性
// @param: strPath 路径
// @ret: DWORD 属性
bool GetAttributes(const _tstring& strPath, DWORD& dwAttr);
DWORD GetAttributes(const _tstring& strPath);
//
// @brief: 设置路径属性
// @param: strPath 路径
// @ret: 成功返回true
bool SetAttributes(const _tstring& strPath, const DWORD& dwAttr);
//
// @brief: 获取文件大小
// @param: strPath 路径
// @ret: 文件大小
unsigned long long GetFileSize(const _tstring& strPath);
//
// @brief: 检查是否为文件
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是否存在 存在返回 true
bool IsFile(const _tstring& strPath);
//
// @brief: 检查是否为文件夹
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是否存在 存在返回 true
bool IsDirectory(const _tstring& strPath);
//
// @brief: 检查路径是否存在
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是否存在 存在返回 true
bool IsExist(const _tstring& strPath);
//
// @brief: 检查路径是否隐藏
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是否存在 存在返回 true
bool IsHidden(const _tstring& strPath);
//
// @brief: 检查路径是否只读
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是否存在 只读返回 true
bool IsReadonly(const _tstring& strPath);
//
// @brief: 判断是否是完整路径
// @param: strPath 文件名, 如: D:\Software\HxDPortableSetup.exe
// @ret: 是返回 true
bool IsFullPath(const _tstring& strPath);
//
// @brief: 获取从 strSrc 到 strDest 的相对路径
// @param: strDest 路径目标
// @param: strSrc 基于路径源
// @ret: 是返回 _tstring 相对路径
_tstring GetRelativePath(const _tstring& strDest, const _tstring& strSrc, bool bFromIsDir = true);
//
// @brief: 判断是否是相对路径
// @param: strPath
// @ret: 是返回 true
bool IsRelative(const _tstring& strPath);
//
// @brief: 判断是否是绝路径
// @param: strPath
// @ret: 是返回 true
bool IsAbsolutePath(const _tstring& strPath);
//
// @brief: 如果路径存在空格, 则使用引号括起来
// @param: strPath 文件名, 如: C:\Program Files (x86)
// @ret: 添加引号 添加引号返回 true
bool QuoteSpaces(_tstring& strPath);
//
// @brief: 删除路径开头和末尾的引号
// @param: strPath 文件名, 如: "C:\Program Files (x86)"
// @ret: 去除引号 去除引号返回 true
bool UnquoteSpaces(_tstring& strPath);
//
// @brief: 获取相对路径的绝对路径
// @param: strPath 文件(夹)相对路径
// @ret: _tstring 转换后的绝对路径
_tstring GetAbsolutePath(const _tstring& strPath);
//
// @brief: 获取读取工作路径的绝对路径
// @param: strPath 文件(夹)相对路径
// @ret: _tstring 转换后的绝对路径
_tstring GetCurrentAbsolutePath(const _tstring& strPath);
//
// @brief: 重命名(夹)
// @param: strSrc 原始文件名
// @param: strDest 目标文件名(绝对路径或仅目标名)
// @ret: 成功返回true
bool Rename(const _tstring& strSrc, const _tstring& strDest);
//
// @brief: 移动文件(夹)
// @param: strSrc 原始文件名
// @param: strDest 目标文件名(绝对路径或仅目标名)
// @ret: 成功返回true
bool Move(const _tstring& strSrc, const _tstring& strDest);
//
// @brief: 拷贝文件(夹)
// @param: strSrc 源路径
// @param: strDest 目的路径(末尾为'\'则认为是复制到文件夹)
// @param: bEmptyDir 是否拷贝空文件夹
// @param: bOverwrites 是否覆盖文件
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: 成功返回true
bool Copy(
const _tstring& strSrc,
const _tstring& strDest,
bool bEmptyDir = true,
bool bOverwrites = false,
int32_t depth = MAX_PATH
);
//
// @brief: 拷贝文件夹
// @param: strSrc 源文件夹
// @param: strDest 目的文件夹
// @param: bEmptyDir 是否拷贝空文件夹
// @param: bOverwrites 是否覆盖文件
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: 成功返回true
bool CopyDir(
const _tstring& strSrc,
const _tstring& strDest,
bool bEmptyDir = true,
bool bOverwrites = false,
int32_t depth = MAX_PATH
);
//
// @brief: 删除文件或文件夹
// @param: strPath 路径
// @ret: 成功返回true
bool Delete(const _tstring& strPath);
//
// @brief: 删除文件
// @param: strPath 路径
// @ret: 成功返回true
bool DeleteArchive(const _tstring& strPath);
//
// @brief: 删除目录(递归删除子目录及文件)
// @param: strPath 路径
// @param: bSubOnly 仅删除子项
// @ret: 成功返回true
bool DeleteDir(const _tstring& strPath, bool bSubOnly = false);
//
// @brief: 创建目录(递归)
// @param: strPath 路径
// @ret: 成功返回true
bool CreateDir(const _tstring& strPath);
//
// @brief: 拷贝文件(夹)(使用SHFileOperation)
// @param: strSrcPath 源路径
// @param: strDestPath 目的路径(末尾为'\'则认为是复制到文件夹)
// @ret: 错误代码 成功返回0
int SHCopy(const _tstring& strSrc, const _tstring& strDest);
//
// @brief: 重命名(夹)(使用SHFileOperation)
// @param: strSrc 原始文件名
// @param: strDest 目标文件名(绝对路径或仅目标名)
// @ret: 错误代码 成功返回0
int SHMove(const _tstring& strSrc, const _tstring& strDest);
//
// @brief: 移动文件(夹)(使用SHFileOperation)
// @param: strSrc 原始文件名
// @param: strDest 目标文件名(绝对路径或仅目标名)
// @ret: 错误代码 成功返回0
int SHRename(const _tstring& strSrc, const _tstring& strDest);
//
// @brief: 删除文件(使用SHFileOperation)
// @param: strPath 路径
// @ret: 错误代码 成功返回0
int SHDelete(const _tstring& strSrc);
//
// @brief: 获取展开环境变量字符串
// @param: strPath 路径
// @ret: _tstring 展开字符串
_tstring GetExpandEnvStrings(const _tstring& strPath);
//
// @brief: 获取环境变量字符串
// @param: strPath 路径
// @ret: _tstring 展开字符串
_tstring GetUnExpandEnvStrings(const _tstring& strPath);
//
// @brief: 获取目录下文件路径
// @param: strDir 指定目录
// @param: extList 扩展名过滤列表, 如: {("exe"), ("txt")}
// @param: bIncludeHide 是否包含隐藏文件
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: std::vector<_tstring> 文件路径列表
std::vector<_tstring> GetPathList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取工作目录下文件路径
// @param: strDir 指定目录
// @param: extList 扩展名过滤列表, 如: {("exe"), ("txt")}
// @param: bIncludeHide 是否包含隐藏文件
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @ret: std::vector<_tstring> 文件路径列表
std::vector<_tstring> GetCurrentPathList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取目录下文件路径
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: dwExclude 排除属性
// @param: dwContain 包含属性
std::vector<FILEINFO> GetFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取工作目录下文件路径
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: dwExclude 排除属性
// @param: dwContain 包含属性
std::vector<FILEINFO> GetCurrentFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取目录下文件路径
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: dwExclude 排除属性
// @param: dwContain 包含属性
std::map<_tstring, FILEINFO> GetPathAndFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取工作目录下文件路径
// @param: strDir 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: dwExclude 排除属性
// @param: dwContain 包含属性
std::map<_tstring, FILEINFO> GetCurrentPathAndFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取符合搜索要求的文件路径
// @param: strDir 指定目录
// @param: strSrcName 指定目录
// @param: depth 目录深度 如: 0:指定目录为根目录, 遍历0层子目录
// @param: dwExclude 排除属性
// @param: dwContain 包含属性
std::vector<_tstring> SearchFiles(
const _tstring& strDir,
const _tstring& strSrcName,
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
//
// @brief: 获取磁盘卷可用空间
// @param: strDir 指定目录, 如 "C:\"
// @ret: ULONGLONG 可用空间
ULONGLONG GetDiskFreeSize(const _tstring& strDir);
//
// @brief: 获取磁盘卷总空间
// @param: strDir 指定目录, 如 "C:\"
// @ret: ULONGLONG 总空间
ULONGLONG GetDiskTotalSize(const _tstring& strDir);
// 已知文件夹获取
_tstring GetNetworkFolder();
_tstring GetComputerFolder();
_tstring GetInternetFolder();
_tstring GetControlPanelFolder();
_tstring GetPrintersFolder();
_tstring GetSyncManagerFolder();
_tstring GetSyncSetupFolder();
_tstring GetConflictFolder();
_tstring GetSyncResultsFolder();
_tstring GetRecycleBinFolder();
_tstring GetConnectionsFolder();
_tstring GetFonts();
_tstring GetDesktop();
_tstring GetStartup();
_tstring GetPrograms();
_tstring GetStartMenu();
_tstring GetRecent();
_tstring GetSendTo();
_tstring GetDocuments();
_tstring GetFavorites();
_tstring GetNetHood();
_tstring GetPrintHood();
_tstring GetTemplates();
_tstring GetCommonStartup();
_tstring GetCommonPrograms();
_tstring GetCommonStartMenu();
_tstring GetPublicDesktop();
_tstring GetProgramData();
_tstring GetCommonTemplates();
_tstring GetPublicDocuments();
_tstring GetRoamingAppData();
_tstring GetLocalAppData();
_tstring GetLocalAppDataLow();
_tstring GetInternetCache();
_tstring GetCookies();
_tstring GetHistory();
_tstring GetSystem();
_tstring GetSystemX86();
_tstring GetWindows();
_tstring GetProfile();
_tstring GetPictures();
_tstring GetProgramFilesX86();
_tstring GetProgramFilesCommonX86();
_tstring GetProgramFilesX64();
_tstring GetProgramFilesCommonX64();
_tstring GetProgramFiles();
_tstring GetProgramFilesCommon();
_tstring GetUserProgramFiles();
_tstring GetUserProgramFilesCommon();
_tstring GetAdminTools();
_tstring GetCommonAdminTools();
_tstring GetMusic();
_tstring GetVideos();
_tstring GetRingtones();
_tstring GetPublicPictures();
_tstring GetPublicMusic();
_tstring GetPublicVideos();
_tstring GetPublicRingtones();
_tstring GetResourceDir();
_tstring GetLocalizedResourcesDir();
_tstring GetCommonOEMLinks();
_tstring GetCDBurning();
_tstring GetUserProfiles();
_tstring GetPlaylists();
_tstring GetSamplePlaylists();
_tstring GetSampleMusic();
_tstring GetSamplePictures();
_tstring GetSampleVideos();
_tstring GetPhotoAlbums();
_tstring GetPublic();
_tstring GetChangeRemovePrograms();
_tstring GetAppUpdates();
_tstring GetAddNewPrograms();
_tstring GetDownloads();
_tstring GetPublicDownloads();
_tstring GetSavedSearches();
_tstring GetQuickLaunch();
_tstring GetContacts();
_tstring GetSidebarParts();
_tstring GetSidebarDefaultParts();
_tstring GetPublicGameTasks();
_tstring GetGameTasks();
_tstring GetSavedGames();
_tstring GetGames();
_tstring GetSEARCH_MAPI();
_tstring GetSEARCH_CSC();
_tstring GetLinks();
_tstring GetUsersFiles();
_tstring GetUsersLibraries();
_tstring GetSearchHome();
_tstring GetOriginalImages();
_tstring GetDocumentsLibrary();
_tstring GetMusicLibrary();
_tstring GetPicturesLibrary();
_tstring GetVideosLibrary();
_tstring GetRecordedTVLibrary();
_tstring GetHomeGroup();
_tstring GetHomeGroupCurrentUser();
_tstring GetDeviceMetadataStore();
_tstring GetLibraries();
_tstring GetPublicLibraries();
_tstring GetUserPinned();
_tstring GetImplicitAppShortcuts();
_tstring GetAccountPictures();
_tstring GetPublicUserTiles();
_tstring GetAppsFolder();
_tstring GetStartMenuAllPrograms();
_tstring GetCommonStartMenuPlaces();
_tstring GetApplicationShortcuts();
_tstring GetRoamingTiles();
_tstring GetRoamedTileImages();
_tstring GetScreenshots();
_tstring GetCameraRoll();
_tstring GetSkyDrive();
_tstring GetOneDrive();
_tstring GetSkyDriveDocuments();
_tstring GetSkyDrivePictures();
_tstring GetSkyDriveMusic();
_tstring GetSkyDriveCameraRoll();
_tstring GetSearchHistory();
_tstring GetSearchTemplates();
_tstring GetCameraRollLibrary();
_tstring GetSavedPictures();
_tstring GetSavedPicturesLibrary();
_tstring GetRetailDemo();
_tstring GetDevice();
_tstring GetDevelopmentFiles();
_tstring GetObjects3D();
_tstring GetAppCaptures();
_tstring GetLocalDocuments();
_tstring GetLocalPictures();
_tstring GetLocalVideos();
_tstring GetLocalMusic();
_tstring GetLocalDownloads();
_tstring GetRecordedCalls();
_tstring GetAllAppMods();
_tstring GetCurrentAppMods();
_tstring GetAppDataDesktop();
_tstring GetAppDataDocuments();
_tstring GetAppDataFavorites();
_tstring GetAppDataProgramData();
}
CPathUtils.cpp
#include "CPathUtils.h"
#include <windows.h>
#include <shlwapi.h>
#include <io.h>
#include <shlobj_core.h>
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Shlwapi.lib")
namespace CPathUtils
{
void _GetPathListEx(
const _tstring& dir,
std::function<bool(const _tstring strPath, const WIN32_FIND_DATA& findData)> cb,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
void _GetPathList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
void _GetFileInfoList(
std::vector<FILEINFO>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
void _GetPathAndPathInfoList(
std::map<_tstring, FILEINFO>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList = {},
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
void _SearchFiles(
std::vector<_tstring>& fileList,
const _tstring& strSrcDir,
const _tstring& strSrcName,
int32_t depth = MAX_PATH,
DWORD dwExclude = 0,
DWORD dwContain = 0
);
_tstring GetCurrentModulePath()
{
TCHAR szCurPath[MAX_PATH] = { 0 };
::GetModuleFileName(NULL, szCurPath, _countof(szCurPath));
return szCurPath;
}
_tstring GetCurrentDir()
{
TCHAR szCurPath[MAX_PATH] = { 0 };
::GetCurrentDirectory(_countof(szCurPath), szCurPath);
return szCurPath;
}
_tstring GetCurrentModuleDir()
{
return GetFileDir(GetCurrentModulePath());
}
_tstring GetCurrentModuleName(bool bHasExt/* = false*/)
{
return GetFileName(GetCurrentModulePath(), bHasExt);
}
_tstring GetFileDriver(const _tstring& strPath)
{
_tstring strResult;
if (strPath.size() > 2 && _T(':') == strPath[1])
{
strResult = strPath.substr(0, 1);
}
return strResult;
}
_tstring GetFileDir(const _tstring& strPath)
{
_tstring strDir = strPath;
for (auto& ch : strDir)
{
if (_T('/') == ch)
{
ch = _T('\\');
}
}
_tstring strResult;
size_t nIndex = strDir.find_last_of(_T('\\'));
if (nIndex != _tstring::npos)
{
strResult = strDir.substr(0, nIndex);
}
return strResult;
}
_tstring GetFileName(const _tstring& strPath, bool bHasExt/* = false*/)
{
_tstring strResult = strPath;
size_t nIndex = strResult.find_last_of(_T('\\'));
if (nIndex != _tstring::npos)
{
strResult = strResult.substr(nIndex + 1);
}
if (!bHasExt)
{
nIndex = strResult.find_last_of(_T('.'));
if (nIndex != _tstring::npos)
{
strResult.resize(nIndex);
}
}
return strResult;
}
_tstring GetFileExt(const _tstring& strPath, bool bHasDot/* = false*/)
{
_tstring strResult = strPath;
size_t nIndex = strResult.find_last_of(_T('.'));
if (nIndex != _tstring::npos)
{
if (bHasDot)
{
strResult = strResult.substr(nIndex);
}
else
{
strResult = strResult.substr(nIndex + 1);
}
}
else
{
strResult = _T("");
}
return strResult;
}
_tstring GetShortPath(const _tstring& strPath)
{
TCHAR szBuf[MAX_PATH] = { 0 };
::GetShortPathName(strPath.c_str(), szBuf, _countof(szBuf));
return szBuf;
}
_tstring GetLongPath(const _tstring& strPath)
{
TCHAR szBuf[MAX_PATH] = { 0 };
::GetLongPathName(strPath.c_str(), szBuf, _countof(szBuf));
return szBuf;
}
_tstring GetFullPath(const _tstring& strPath)
{
TCHAR szBuf[MAX_PATH] = { 0 };
TCHAR* pFilePart = nullptr;
::GetFullPathName(strPath.c_str(), _countof(szBuf), szBuf, &pFilePart);
return szBuf;
}
_tstring DosPathToNtPath(const _tstring& strPath)
{
_tstring strResultPath;
TCHAR szDriveStrings[MAX_PATH] = { 0 };
TCHAR szDosBuf[MAX_PATH] = { 0 };
LPTSTR pDriveStr = NULL;
do
{
// 获取盘符名到缓冲
if (!::GetLogicalDriveStrings(_countof(szDriveStrings), szDriveStrings))
{
break;
}
// 遍历盘符名
for (int i = 0; i < _countof(szDriveStrings); i += 4)
{
pDriveStr = &szDriveStrings[i];
pDriveStr[2] = _T('\0');
// 查询盘符对应的DOS设备名称
DWORD dwCch = ::QueryDosDevice(pDriveStr, szDosBuf, _countof(szDosBuf));
if (!dwCch)
{
break;
}
// 结尾有 2 个 NULL, 减去 2 获得字符长度
if (dwCch >= 2)
{
dwCch -= 2;
}
if (strPath.size() < dwCch)
{
break;
}
// 路径拼接
if (_T('\\') == strPath[dwCch] && 0 == _tcsncmp(strPath.c_str(), szDosBuf, dwCch))
{
strResultPath = pDriveStr;
strResultPath += &strPath[dwCch];
break;
}
}
} while (false);
return strResultPath;
}
_tstring NtPathToDosPath(const _tstring& strPath)
{
_tstring strResultPath;
TCHAR szDosBuf[MAX_PATH] = { 0 };
do
{
if (strPath.size() < 2)
{
break;
}
// 非 NT 路径则不处理
if (_T(':') != strPath[1] || _T('\\') == strPath[0])
{
break;
}
// 查询盘符对应的DOS设备名称
if (!::QueryDosDevice(strPath.substr(0, 2).c_str(), szDosBuf, _countof(szDosBuf)))
{
break;
}
strResultPath = szDosBuf;
strResultPath += strPath.substr(2);
} while (false);
return strResultPath;
}
bool GetAttributes(const _tstring& strPath, DWORD& dwAttr)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
dwAttr = attr.dwFileAttributes;
return true;
}
DWORD GetAttributes(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return 0;
}
return attr.dwFileAttributes;
}
bool SetAttributes(const _tstring& strPath, const DWORD& dwAttr)
{
return ::SetFileAttributes(strPath.c_str(), dwAttr);
}
unsigned long long GetFileSize(const _tstring& strPath)
{
unsigned long long ullSize = 0;
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return 0;
}
if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
return 0;
}
ullSize = (unsigned long long)attr.nFileSizeHigh << 32 | attr.nFileSizeLow;
return ullSize;
}
bool IsFile(const _tstring& strPath)
{
DWORD dwAttr = 0;
if (!GetAttributes(strPath, dwAttr))
{
return false;
}
return 0 == (dwAttr & FILE_ATTRIBUTE_DIRECTORY);
}
bool IsDirectory(const _tstring& strPath)
{
return 0 != (GetAttributes(strPath) & FILE_ATTRIBUTE_DIRECTORY);
}
bool IsExist(const _tstring& strPath)
{
return 0 == _taccess_s(strPath.c_str(), 00);
}
bool IsReadonly(const _tstring& strPath)
{
return 0 != (GetAttributes(strPath) & FILE_ATTRIBUTE_READONLY);
}
bool IsHidden(const _tstring& strPath)
{
WIN32_FILE_ATTRIBUTE_DATA attr = { 0 };
if (!::GetFileAttributesEx(strPath.c_str(), GetFileExInfoStandard, &attr))
{
return false;
}
return attr.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN;
}
bool IsFullPath(const _tstring& strPath)
{
if (::PathIsRelative(strPath.c_str()) || ::PathIsUNC(strPath.c_str()))
{
return false;
}
return true;
}
_tstring GetRelativePath(const _tstring& strDest, const _tstring& strSrc, bool bFromIsDir/* = true*/)
{
_TCHAR szRelativePath[MAX_PATH] = { 0 };
DWORD dwAttrFrom = 0;
if (bFromIsDir)
{
dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY;
}
if (::PathRelativePathTo(szRelativePath, strSrc.c_str(), dwAttrFrom, strDest.c_str(), 0))
{
return szRelativePath;
}
return strDest;
}
bool IsRelative(const _tstring& strPath)
{
return ::PathIsRelative(strPath.c_str());
}
bool IsAbsolutePath(const _tstring& strPath)
{
return !::PathIsRelative(strPath.c_str());
}
bool QuoteSpaces(_tstring& strPath)
{
if (strPath.empty())
{
return false;
}
size_t nFindBegin = strPath.find_first_of(_T('\"'));
size_t nFindEnd = strPath.find_last_of(_T('\"'));
//两边已经有引号
if (0 == nFindBegin && (strPath.size() - 1 == nFindEnd))
{
return false;
}
//检查是否有空格
if (_tstring::npos == strPath.find(_T(' ')))
{
return false;
}
strPath = _T("\"") + strPath + _T("\"");
return true;
}
bool UnquoteSpaces(_tstring& strPath)
{
size_t nFindBegin = strPath.find_first_of(_T('\"'));
size_t nFindEnd = strPath.find_last_of(_T('\"'));
if (_tstring::npos == nFindBegin || _tstring::npos == nFindEnd)
{
return false;
}
strPath = strPath.substr(nFindBegin + 1, strPath.size() - 2);
return true;
}
_tstring GetAbsolutePath(const _tstring& strPath)
{
_tstring strResult = strPath;
if (PathIsRelative(strPath.c_str()))
{
if (strPath.empty())
{
strResult = GetCurrentModuleDir();
}
else
{
strResult = GetCurrentModuleDir() + _T("\\") + strPath;
}
}
return strResult;
}
_tstring GetCurrentAbsolutePath(const _tstring& strPath)
{
_tstring strResult = strPath;
if (PathIsRelative(strPath.c_str()))
{
if (strPath.empty())
{
strResult = GetCurrentDir();
}
else
{
strResult = GetCurrentDir() + _T("\\") + strPath;
}
}
return strResult;
}
bool Rename(const _tstring& strSrc, const _tstring& strDest)
{
return Move(strSrc, strDest);
}
bool Move(const _tstring& strSrc, const _tstring& strDest)
{
_tstring strSrcPath = strSrc;
_tstring strDestPath = strDest;
//不存在则提前返回
if (!IsExist(strSrcPath))
{
return false;
}
strSrcPath = GetAbsolutePath(strSrc);
strDestPath = GetAbsolutePath(strDest);
_tstring strSrcName = GetFileName(strSrc, true);
_tstring strDestDir = GetFileDir(strDestPath);
//末尾为反斜杠则认为是移动到文件夹内
if (_T('\\') == strDestPath.back())
{
strDestPath += strSrcName;
}
//检查目标文件夹, 不存在则创建
if (!IsDirectory(strDestDir))
{
CreateDir(strDestDir);
}
return ::MoveFileEx(strSrcPath.c_str(), strDestPath.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
}
bool Copy(
const _tstring& strSrc,
const _tstring& strDest,
bool bEmptyDir/* = true*/,
bool bOverwrites/* = false*/,
int32_t depth/* = MAX_PATH*/
)
{
//到达深度限制返回
if (depth < 0)
{
return true;
}
if (strSrc.empty() || strDest.empty())
{
return false;
}
_tstring strSrcName = GetFileName(strSrc, true);
// 文件拷贝
if (IsFile(strSrc))
{
// 拷贝到目录
if (_T('\\') == strDest.back())
{
_tstring strDir = strDest.substr(0, strDest.size() - 1);
_tstring strFile = strDest + strSrcName;
if (!strDir.empty() && !IsDirectory(strDir))
{
CreateDir(strDir);
}
if (!bOverwrites && IsFile(strFile))
{
return true;
}
return ::CopyFile(strSrc.c_str(), strFile.c_str(), FALSE);
}
else
{
_tstring strDestDir = strDest;
_tstring strDestName = strSrcName;
if (!IsDirectory(strDest))
{
strDestDir = GetFileDir(strDest);
strDestName = GetFileName(strDest, true);
}
if (!strDestDir.empty() && !IsDirectory(strDestDir))
{
CreateDir(strDestDir);
}
_tstring strDestFile = strDestName;
if (!strDestDir.empty())
{
strDestFile = strDestDir + _T("\\") + strDestName;
}
if (!bOverwrites && IsFile(strDestFile))
{
return true;
}
return ::CopyFile(strSrc.c_str(), strDestFile.c_str(), FALSE);
}
}
else
{
// 不是文件夹且所在文件夹不存在则认为失败
if (!IsDirectory(strSrc) && !IsDirectory(GetFileDir(strSrc)))
{
return false;
}
_tstring strCopyDest = strDest;
if (IsDirectory(strSrc) && _T('\\') == strCopyDest.back())
{
strCopyDest = strDest + strSrcName;
}
return CopyDir(strSrc, strCopyDest, bEmptyDir, bOverwrites, depth);
}
return false;
}
bool CopyDir(
const _tstring& strSrc,
const _tstring& strDest,
bool bEmptyDir/* = true*/,
bool bOverwrites/* = false*/,
int32_t depth/* = MAX_PATH*/
)
{
//到达深度限制返回
if (depth < 0)
{
return true;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
_tstring strFindName;
_tstring strFindFile = strSrc;
_tstring strFindDir = strSrc;
//文件夹则匹配全部类型文件
if (IsDirectory(strSrc))
{
strFindFile = strSrc + _T("\\*");
}
else
{
strFindDir = GetFileDir(strSrc);
strFindName = GetFileName(strSrc, true);
}
if (!IsDirectory(strFindDir))
{
return false;
}
//先拷贝符合规则的文件
do
{
hFindHandle = FindFirstFile(strFindFile.c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
break;
}
do
{
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
//拷贝文件
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
_tstring strPathTo = strDest + _T("\\") + findData.cFileName;
if (!IsDirectory(strDest))
{
CreateDir(strDest);
}
_tstring strFileFrom = strFindDir + _T("\\") + findData.cFileName;
if (!bOverwrites && IsFile(strPathTo))
{
return true;
}
::CopyFile(strFileFrom.c_str(), strPathTo.c_str(), FALSE);
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
} while (false);
//后拷贝文件夹
do
{
hFindHandle = FindFirstFile((strFindDir + _T("\\*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
break;
}
do
{
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
//拷贝文件
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
_tstring strPathTo = strDest + _T("\\") + findData.cFileName;
if (bEmptyDir && !IsDirectory(strPathTo))
{
CreateDir(strPathTo);
}
_tstring strFileFrom = strFindDir + _T("\\") + findData.cFileName;
if (strFindName.empty())
{
CopyDir(strFileFrom, strPathTo, bEmptyDir, bOverwrites, depth - 1);
}
else
{
CopyDir(strFileFrom + _T("\\") + strFindName, strPathTo, bEmptyDir, bOverwrites, depth - 1);
}
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
} while (false);
return true;
}
bool Delete(const _tstring& strPath)
{
if (IsFile(strPath))
{
return DeleteArchive(strPath);
}
if (IsDirectory(strPath))
{
return DeleteDir(strPath);
}
return false;
}
bool DeleteArchive(const _tstring& strPath)
{
if (strPath.empty())
{
return false;
}
return ::DeleteFile(strPath.c_str());
}
bool DeleteDir(const _tstring& strResult, bool bSubOnly/* = false*/)
{
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
if (strResult.empty())
{
return false;
}
hFindHandle = FindFirstFile((strResult + _T("\\*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return false;
}
do
{
_tstring strFilePath = strResult + _T("\\") + findData.cFileName;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //删除目录
{
DeleteDir(strFilePath, false);
continue;
}
else //删除文件
{
::DeleteFile(strFilePath.c_str());
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
if (bSubOnly)
{
return true;
}
return ::RemoveDirectory(strResult.c_str());
}
bool CreateDir(const _tstring& strPath)
{
_tstring strDriver; //驱动器号, 如 D:
_tstring strSubPath = strPath; //路径, 如 Test\1\2\3
if (strPath.empty())
{
return false;
}
//获取盘符
do
{
size_t nFindIndex = strPath.find_first_of(':'); //检查是否有驱动器号
if (nFindIndex == _tstring::npos)
{
break;
}
strDriver = strPath.substr(0, nFindIndex + 1); //得到驱动器号, 如 D:
nFindIndex = strPath.find(_T("\\"), nFindIndex);
if (nFindIndex == _tstring::npos)
{
break;
}
strSubPath = strPath.substr(nFindIndex + 1); //得到路径, 如 Test\1\2\3
} while (false);
_tstring strDestDir;
size_t nFindBegin = 0;
size_t nFindIndex = 0;
do
{
nFindIndex = strSubPath.find(_T("\\"), nFindBegin);
if (nFindIndex != _tstring::npos)
{
strDestDir = strSubPath.substr(0, nFindIndex);
nFindBegin = nFindIndex + 1;
}
else
{
strDestDir = strSubPath;
}
if (!strDriver.empty())
{
strDestDir = strDriver + _T("\\") + strDestDir;
}
if (!::CreateDirectory(strDestDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != ::GetLastError())
{
return false;
}
} while (nFindIndex != _tstring::npos);
return true;
}
int SHCopy(const _tstring& strSrc, const _tstring& strDest)
{
_tstring strFrom = GetAbsolutePath(strSrc) + _T('\0');
_tstring strTo = GetAbsolutePath(strDest) + _T('\0');
SHFILEOPSTRUCT sfos = { 0 };
sfos.wFunc = FO_COPY;
sfos.pFrom = strFrom.c_str(); //注意 此字符串必须以双 null 结尾
sfos.pTo = strTo.c_str(); //注意 此字符串必须以双 null 结尾
sfos.fFlags = FOF_NO_UI | FOF_FILESONLY;
return SHFileOperation(&sfos);
}
int SHMove(const _tstring& strSrc, const _tstring& strDest)
{
_tstring strFrom = GetAbsolutePath(strSrc) + _T('\0');
_tstring strTo = GetAbsolutePath(strDest) + _T('\0');
SHFILEOPSTRUCT sfos = { 0 };
sfos.wFunc = FO_MOVE;
sfos.pFrom = strFrom.c_str(); //注意 此字符串必须以双 null 结尾
sfos.pTo = strTo.c_str(); //注意 此字符串必须以双 null 结尾
sfos.fFlags = FOF_NO_UI;
return SHFileOperation(&sfos);
}
int SHRename(const _tstring& strSrc, const _tstring& strDest)
{
_tstring strFrom = GetAbsolutePath(strSrc) + _T('\0');
_tstring strTo = GetAbsolutePath(strDest) + _T('\0');
SHFILEOPSTRUCT sfos = { 0 };
sfos.wFunc = FO_RENAME;
sfos.pFrom = strFrom.c_str(); //注意 此字符串必须以双 null 结尾
sfos.pTo = strTo.c_str(); //注意 此字符串必须以双 null 结尾
sfos.fFlags = FOF_NO_UI;
return SHFileOperation(&sfos);
}
int SHDelete(const _tstring& strSrc)
{
_tstring strFrom = GetAbsolutePath(strSrc) + _T('\0');
SHFILEOPSTRUCT sfos = { 0 };
sfos.wFunc = FO_DELETE;
sfos.pFrom = strFrom.c_str(); //注意 此字符串必须以双 null 结尾
sfos.fFlags = FOF_NO_UI;
return SHFileOperation(&sfos);
}
_tstring GetExpandEnvStrings(const _tstring& strPath)
{
TCHAR szBuf[MAX_PATH] = { 0 };
::ExpandEnvironmentStrings(strPath.c_str(), szBuf, _countof(szBuf));
return szBuf;
}
_tstring GetUnExpandEnvStrings(const _tstring& strPath)
{
TCHAR szBuf[MAX_PATH] = { 0 };
::PathUnExpandEnvStrings(strPath.c_str(), szBuf, _countof(szBuf));
return szBuf;
}
std::vector<_tstring> GetPathList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::vector<_tstring> fileList;
_tstring strSrcDir = GetAbsolutePath(strDir);
_GetPathList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::vector<_tstring> GetCurrentPathList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::vector<_tstring> fileList;
_tstring strSrcDir = GetCurrentAbsolutePath(strDir);
_GetPathList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::vector<FILEINFO> GetFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::vector<FILEINFO> fileList;
_tstring strSrcDir = GetAbsolutePath(strDir);
_GetFileInfoList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::vector<FILEINFO> GetCurrentFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::vector<FILEINFO> fileList;
_tstring strSrcDir = GetCurrentAbsolutePath(strDir);
_GetFileInfoList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::map<_tstring, FILEINFO> GetPathAndFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::map<_tstring, FILEINFO> fileList;
_tstring strSrcDir = GetAbsolutePath(strDir);
_GetPathAndPathInfoList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::map<_tstring, FILEINFO> GetCurrentPathAndFileInfoList(
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::map<_tstring, FILEINFO> fileList;
_tstring strSrcDir = GetCurrentAbsolutePath(strDir);
_GetPathAndPathInfoList(fileList, strSrcDir, extList, depth, dwExclude, dwContain);
return fileList;
}
std::vector<_tstring> SearchFiles(
const _tstring& strFile,
const _tstring& strSrcName,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
std::vector<_tstring> fileList;
_tstring strSrcDir = GetAbsolutePath(strFile);
_tstring strName = strSrcName;
if (strName.empty())
{
strName = _T("*");
}
if (GetFileDir(strName).empty())
{
_SearchFiles(fileList, strSrcDir, strName, depth, dwExclude, dwContain);
}
return fileList;
}
void _SearchFiles(
std::vector<_tstring>& fileList,
const _tstring& strSrcDir,
const _tstring& strSrcName,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
if (!IsDirectory(strSrcDir))
{
return;
}
//先搜索符合规则的文件
do
{
_tstring strFindFile = strSrcDir + _T("\\") + strSrcName;
hFindHandle = FindFirstFile(strFindFile.c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
break;
}
do
{
bool bExclude = false;
bool bContain = false;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
// 检查排除属性
if (0 != dwExclude && (0 != (findData.dwFileAttributes & dwExclude)))
{
bExclude = true;
}
// 检查包含属性
if (0 == dwContain)
{
bContain = true;
}
else if (dwContain == (findData.dwFileAttributes & dwContain))
{
bContain = true;
}
// 属性检查
if (!bExclude && bContain && (0 == (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)))
{
fileList.emplace_back(strSrcDir + _T("\\") + findData.cFileName);
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
} while (false);
//后搜索文件夹
do
{
_tstring strFindFile = strSrcDir + _T("\\*");
hFindHandle = FindFirstFile(strFindFile.c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
break;
}
do
{
bool bExclude = false;
bool bContain = false;
//上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
_SearchFiles(fileList, strSrcDir + _T("\\") + findData.cFileName, strSrcName, depth - 1, dwExclude, dwContain);
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
} while (false);
}
void _GetPathListEx(
const _tstring& dir,
std::function<bool(const _tstring strPath, const WIN32_FIND_DATA& findData)> cb,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
//到达深度限制返回
if (depth < 0)
{
return;
}
WIN32_FIND_DATA findData = { 0 };
HANDLE hFindHandle = INVALID_HANDLE_VALUE;
hFindHandle = ::FindFirstFile((dir + _T("\\*")).c_str(), &findData);
if (INVALID_HANDLE_VALUE == hFindHandle)
{
return;
}
do
{
// 上一级目录与当前目录跳过
if (0 == _tcscmp(findData.cFileName, _T(".")) || 0 == _tcscmp(findData.cFileName, _T("..")))
{
continue;
}
bool bAbort = false;
bool bExclude = false;
bool bContain = false;
// 检查排除属性
if (0 != dwExclude && (0 != (findData.dwFileAttributes & dwExclude)))
{
bExclude = true;
}
// 检查包含属性
if (0 == dwContain)
{
bContain = true;
}
else if (dwContain == (findData.dwFileAttributes & dwContain))
{
bContain = true;
}
// 路径
_tstring strPath = dir + _T("\\") + findData.cFileName;
if (!bExclude && bContain && cb)
{
if (extList.empty())
{
bAbort = !cb(strPath, findData);
if (bAbort)
{
break;
}
}
else
{
// 获取扩展名
_tstring strExtName = findData.cFileName;
size_t nIndex = strExtName.find_last_of(_T('.'));
if (nIndex != _tstring::npos)
{
strExtName = strExtName.substr(nIndex + 1);
}
else
{
strExtName = _T("");
}
// 进行扩展名过滤
for (const auto& item : extList)
{
if (0 == _tcsicmp(item.c_str(), strExtName.c_str()))
{
bAbort = !cb(strPath, findData);
if (bAbort)
{
break;
}
}
}
}
}
if (bAbort)
{
break;
}
// 目录
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
_GetPathListEx(strPath, cb, extList, depth - 1);
}
} while (::FindNextFile(hFindHandle, &findData));
::FindClose(hFindHandle);
}
void _GetPathList(
std::vector<_tstring>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth /* = MAX_PATH */,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
_GetPathListEx(strDir, [&fileList, &extList, dwExclude, dwContain](const _tstring strPath, const WIN32_FIND_DATA& findData) -> bool {
fileList.push_back(strPath);
return true;
}, {}, depth, dwExclude, dwContain
);
}
void _GetFileInfoList(
std::vector<FILEINFO>& fileList,
const _tstring& strDir,
const std::vector<_tstring>& extList/* = {}*/,
int32_t depth/* = MAX_PATH*/,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
_GetPathListEx(strDir, [&fileList, &extList, dwExclude, dwContain](const _tstring strPath, const WIN32_FIND_DATA& findData) -> bool {
FILEINFO info;
info.m_filePath = strPath;
info.m_fileSize = (unsigned long long)findData.nFileSizeHigh << 32 | findData.nFileSizeLow;
info.m_ftCreationTime = *(size_t*)&findData.ftCreationTime;
info.m_ftLastAccessTime = *(size_t*)&findData.ftLastAccessTime;
info.m_ftLastWriteTime = *(size_t*)&findData.ftLastWriteTime;
info.m_fileAttributes = findData.dwFileAttributes;
info.m_ftCreationTime = (info.m_ftCreationTime - 116444736000000000) / 10000000;
info.m_ftLastAccessTime = (info.m_ftLastAccessTime - 116444736000000000) / 10000000;
info.m_ftLastWriteTime = (info.m_ftLastWriteTime - 116444736000000000) / 10000000;
fileList.push_back(info);
return true;
}, {}, depth, dwExclude, dwContain
);
}
void _GetPathAndPathInfoList(
std::map<_tstring, FILEINFO>& fileList,
const _tstring& dir,
const std::vector<_tstring>& extList /* = {} */,
int32_t depth /* = MAX_PATH */,
DWORD dwExclude/* = 0*/,
DWORD dwContain/* = 0*/
)
{
_GetPathListEx(dir, [&fileList, &extList, dwExclude, dwContain](const _tstring strPath, const WIN32_FIND_DATA& findData) -> bool {
FILEINFO info;
info.m_filePath = strPath;
info.m_fileSize = (unsigned long long)findData.nFileSizeHigh << 32 | findData.nFileSizeLow;
info.m_ftCreationTime = *(size_t*)&findData.ftCreationTime;
info.m_ftLastAccessTime = *(size_t*)&findData.ftLastAccessTime;
info.m_ftLastWriteTime = *(size_t*)&findData.ftLastWriteTime;
info.m_fileAttributes = findData.dwFileAttributes;
info.m_ftCreationTime = (info.m_ftCreationTime - 116444736000000000) / 10000000;
info.m_ftLastAccessTime = (info.m_ftLastAccessTime - 116444736000000000) / 10000000;
info.m_ftLastWriteTime = (info.m_ftLastWriteTime - 116444736000000000) / 10000000;
fileList.emplace(std::make_pair(strPath, info));
return true;
}, {}, depth, dwExclude, dwContain
);
}
ULONGLONG GetDiskFreeSize(const _tstring& strDir)
{
ULARGE_INTEGER ullFreeBytesAvailableToCaller = { 0 };
ULARGE_INTEGER ullTotalNumberOfBytes = { 0 };
ULARGE_INTEGER ullTotalNumberOfFreeBytes = { 0 };
::GetDiskFreeSpaceEx(strDir.c_str(),
&ullFreeBytesAvailableToCaller,
&ullTotalNumberOfBytes,
&ullTotalNumberOfFreeBytes
);
return ullTotalNumberOfFreeBytes.QuadPart;
}
ULONGLONG GetDiskTotalSize(const _tstring& strDir)
{
ULARGE_INTEGER ullFreeBytesAvailableToCaller = { 0 };
ULARGE_INTEGER ullTotalNumberOfBytes = { 0 };
ULARGE_INTEGER ullTotalNumberOfFreeBytes = { 0 };
::GetDiskFreeSpaceEx(strDir.c_str(),
&ullFreeBytesAvailableToCaller,
&ullTotalNumberOfBytes,
&ullTotalNumberOfFreeBytes
);
return ullTotalNumberOfBytes.QuadPart;
}
_tstring GetKnownFolder(_In_ REFKNOWNFOLDERID rfid)
{
_tstring strFolder;
LPWSTR pstr = NULL;
HRESULT hr = S_OK;
hr = SHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &pstr);
if (NULL != pstr)
{
#ifdef _UNICODE
strFolder = pstr;
#else
CHAR szBuf[MAX_PATH] = { 0 };
int nConverted = ::WideCharToMultiByte(CP_ACP, 0, pstr, -1, szBuf, _countof(szBuf), NULL, NULL);
if (0 != nConverted)
{
strFolder = szBuf;
}
#endif
CoTaskMemFree(pstr);
}
return strFolder;
}
_tstring GetNetworkFolder() { return GetKnownFolder(FOLDERID_NetworkFolder); }
_tstring GetComputerFolder() { return GetKnownFolder(FOLDERID_ComputerFolder); }
_tstring GetInternetFolder() { return GetKnownFolder(FOLDERID_InternetFolder); }
_tstring GetControlPanelFolder() { return GetKnownFolder(FOLDERID_ControlPanelFolder); }
_tstring GetPrintersFolder() { return GetKnownFolder(FOLDERID_PrintersFolder); }
_tstring GetSyncManagerFolder() { return GetKnownFolder(FOLDERID_SyncManagerFolder); }
_tstring GetSyncSetupFolder() { return GetKnownFolder(FOLDERID_SyncSetupFolder); }
_tstring GetConflictFolder() { return GetKnownFolder(FOLDERID_ConflictFolder); }
_tstring GetSyncResultsFolder() { return GetKnownFolder(FOLDERID_SyncResultsFolder); }
_tstring GetRecycleBinFolder() { return GetKnownFolder(FOLDERID_RecycleBinFolder); }
_tstring GetConnectionsFolder() { return GetKnownFolder(FOLDERID_ConnectionsFolder); }
_tstring GetFonts() { return GetKnownFolder(FOLDERID_Fonts); }
_tstring GetDesktop() { return GetKnownFolder(FOLDERID_Desktop); }
_tstring GetStartup() { return GetKnownFolder(FOLDERID_Startup); }
_tstring GetPrograms() { return GetKnownFolder(FOLDERID_Programs); }
_tstring GetStartMenu() { return GetKnownFolder(FOLDERID_StartMenu); }
_tstring GetRecent() { return GetKnownFolder(FOLDERID_Recent); }
_tstring GetSendTo() { return GetKnownFolder(FOLDERID_SendTo); }
_tstring GetDocuments() { return GetKnownFolder(FOLDERID_Documents); }
_tstring GetFavorites() { return GetKnownFolder(FOLDERID_Favorites); }
_tstring GetNetHood() { return GetKnownFolder(FOLDERID_NetHood); }
_tstring GetPrintHood() { return GetKnownFolder(FOLDERID_PrintHood); }
_tstring GetTemplates() { return GetKnownFolder(FOLDERID_Templates); }
_tstring GetCommonStartup() { return GetKnownFolder(FOLDERID_CommonStartup); }
_tstring GetCommonPrograms() { return GetKnownFolder(FOLDERID_CommonPrograms); }
_tstring GetCommonStartMenu() { return GetKnownFolder(FOLDERID_CommonStartMenu); }
_tstring GetPublicDesktop() { return GetKnownFolder(FOLDERID_PublicDesktop); }
_tstring GetProgramData() { return GetKnownFolder(FOLDERID_ProgramData); }
_tstring GetCommonTemplates() { return GetKnownFolder(FOLDERID_CommonTemplates); }
_tstring GetPublicDocuments() { return GetKnownFolder(FOLDERID_PublicDocuments); }
_tstring GetRoamingAppData() { return GetKnownFolder(FOLDERID_RoamingAppData); }
_tstring GetLocalAppData() { return GetKnownFolder(FOLDERID_LocalAppData); }
_tstring GetLocalAppDataLow() { return GetKnownFolder(FOLDERID_LocalAppDataLow); }
_tstring GetInternetCache() { return GetKnownFolder(FOLDERID_InternetCache); }
_tstring GetCookies() { return GetKnownFolder(FOLDERID_Cookies); }
_tstring GetHistory() { return GetKnownFolder(FOLDERID_History); }
_tstring GetSystem() { return GetKnownFolder(FOLDERID_System); }
_tstring GetSystemX86() { return GetKnownFolder(FOLDERID_SystemX86); }
_tstring GetWindows() { return GetKnownFolder(FOLDERID_Windows); }
_tstring GetProfile() { return GetKnownFolder(FOLDERID_Profile); }
_tstring GetPictures() { return GetKnownFolder(FOLDERID_Pictures); }
_tstring GetProgramFilesX86() { return GetKnownFolder(FOLDERID_ProgramFilesX86); }
_tstring GetProgramFilesCommonX86() { return GetKnownFolder(FOLDERID_ProgramFilesCommonX86); }
_tstring GetProgramFilesX64() { return GetKnownFolder(FOLDERID_ProgramFilesX64); }
_tstring GetProgramFilesCommonX64() { return GetKnownFolder(FOLDERID_ProgramFilesCommonX64); }
_tstring GetProgramFiles() { return GetKnownFolder(FOLDERID_ProgramFiles); }
_tstring GetProgramFilesCommon() { return GetKnownFolder(FOLDERID_ProgramFilesCommon); }
_tstring GetUserProgramFiles() { return GetKnownFolder(FOLDERID_UserProgramFiles); }
_tstring GetUserProgramFilesCommon() { return GetKnownFolder(FOLDERID_UserProgramFilesCommon); }
_tstring GetAdminTools() { return GetKnownFolder(FOLDERID_AdminTools); }
_tstring GetCommonAdminTools() { return GetKnownFolder(FOLDERID_CommonAdminTools); }
_tstring GetMusic() { return GetKnownFolder(FOLDERID_Music); }
_tstring GetVideos() { return GetKnownFolder(FOLDERID_Videos); }
_tstring GetRingtones() { return GetKnownFolder(FOLDERID_Ringtones); }
_tstring GetPublicPictures() { return GetKnownFolder(FOLDERID_PublicPictures); }
_tstring GetPublicMusic() { return GetKnownFolder(FOLDERID_PublicMusic); }
_tstring GetPublicVideos() { return GetKnownFolder(FOLDERID_PublicVideos); }
_tstring GetPublicRingtones() { return GetKnownFolder(FOLDERID_PublicRingtones); }
_tstring GetResourceDir() { return GetKnownFolder(FOLDERID_ResourceDir); }
_tstring GetLocalizedResourcesDir() { return GetKnownFolder(FOLDERID_LocalizedResourcesDir); }
_tstring GetCommonOEMLinks() { return GetKnownFolder(FOLDERID_CommonOEMLinks); }
_tstring GetCDBurning() { return GetKnownFolder(FOLDERID_CDBurning); }
_tstring GetUserProfiles() { return GetKnownFolder(FOLDERID_UserProfiles); }
_tstring GetPlaylists() { return GetKnownFolder(FOLDERID_Playlists); }
_tstring GetSamplePlaylists() { return GetKnownFolder(FOLDERID_SamplePlaylists); }
_tstring GetSampleMusic() { return GetKnownFolder(FOLDERID_SampleMusic); }
_tstring GetSamplePictures() { return GetKnownFolder(FOLDERID_SamplePictures); }
_tstring GetSampleVideos() { return GetKnownFolder(FOLDERID_SampleVideos); }
_tstring GetPhotoAlbums() { return GetKnownFolder(FOLDERID_PhotoAlbums); }
_tstring GetPublic() { return GetKnownFolder(FOLDERID_Public); }
_tstring GetChangeRemovePrograms() { return GetKnownFolder(FOLDERID_ChangeRemovePrograms); }
_tstring GetAppUpdates() { return GetKnownFolder(FOLDERID_AppUpdates); }
_tstring GetAddNewPrograms() { return GetKnownFolder(FOLDERID_AddNewPrograms); }
_tstring GetDownloads() { return GetKnownFolder(FOLDERID_Downloads); }
_tstring GetPublicDownloads() { return GetKnownFolder(FOLDERID_PublicDownloads); }
_tstring GetSavedSearches() { return GetKnownFolder(FOLDERID_SavedSearches); }
_tstring GetQuickLaunch() { return GetKnownFolder(FOLDERID_QuickLaunch); }
_tstring GetContacts() { return GetKnownFolder(FOLDERID_Contacts); }
_tstring GetSidebarParts() { return GetKnownFolder(FOLDERID_SidebarParts); }
_tstring GetSidebarDefaultParts() { return GetKnownFolder(FOLDERID_SidebarDefaultParts); }
_tstring GetPublicGameTasks() { return GetKnownFolder(FOLDERID_PublicGameTasks); }
_tstring GetGameTasks() { return GetKnownFolder(FOLDERID_GameTasks); }
_tstring GetSavedGames() { return GetKnownFolder(FOLDERID_SavedGames); }
_tstring GetGames() { return GetKnownFolder(FOLDERID_Games); }
_tstring GetSEARCH_MAPI() { return GetKnownFolder(FOLDERID_SEARCH_MAPI); }
_tstring GetSEARCH_CSC() { return GetKnownFolder(FOLDERID_SEARCH_CSC); }
_tstring GetLinks() { return GetKnownFolder(FOLDERID_Links); }
_tstring GetUsersFiles() { return GetKnownFolder(FOLDERID_UsersFiles); }
_tstring GetUsersLibraries() { return GetKnownFolder(FOLDERID_UsersLibraries); }
_tstring GetSearchHome() { return GetKnownFolder(FOLDERID_SearchHome); }
_tstring GetOriginalImages() { return GetKnownFolder(FOLDERID_OriginalImages); }
_tstring GetDocumentsLibrary() { return GetKnownFolder(FOLDERID_DocumentsLibrary); }
_tstring GetMusicLibrary() { return GetKnownFolder(FOLDERID_MusicLibrary); }
_tstring GetPicturesLibrary() { return GetKnownFolder(FOLDERID_PicturesLibrary); }
_tstring GetVideosLibrary() { return GetKnownFolder(FOLDERID_VideosLibrary); }
_tstring GetRecordedTVLibrary() { return GetKnownFolder(FOLDERID_RecordedTVLibrary); }
_tstring GetHomeGroup() { return GetKnownFolder(FOLDERID_HomeGroup); }
_tstring GetHomeGroupCurrentUser() { return GetKnownFolder(FOLDERID_HomeGroupCurrentUser); }
_tstring GetDeviceMetadataStore() { return GetKnownFolder(FOLDERID_DeviceMetadataStore); }
_tstring GetLibraries() { return GetKnownFolder(FOLDERID_Libraries); }
_tstring GetPublicLibraries() { return GetKnownFolder(FOLDERID_PublicLibraries); }
_tstring GetUserPinned() { return GetKnownFolder(FOLDERID_UserPinned); }
_tstring GetImplicitAppShortcuts() { return GetKnownFolder(FOLDERID_ImplicitAppShortcuts); }
_tstring GetAccountPictures() { return GetKnownFolder(FOLDERID_AccountPictures); }
_tstring GetPublicUserTiles() { return GetKnownFolder(FOLDERID_PublicUserTiles); }
_tstring GetAppsFolder() { return GetKnownFolder(FOLDERID_AppsFolder); }
_tstring GetStartMenuAllPrograms() { return GetKnownFolder(FOLDERID_StartMenuAllPrograms); }
_tstring GetCommonStartMenuPlaces() { return GetKnownFolder(FOLDERID_CommonStartMenuPlaces); }
_tstring GetApplicationShortcuts() { return GetKnownFolder(FOLDERID_ApplicationShortcuts); }
_tstring GetRoamingTiles() { return GetKnownFolder(FOLDERID_RoamingTiles); }
_tstring GetRoamedTileImages() { return GetKnownFolder(FOLDERID_RoamedTileImages); }
_tstring GetScreenshots() { return GetKnownFolder(FOLDERID_Screenshots); }
_tstring GetCameraRoll() { return GetKnownFolder(FOLDERID_CameraRoll); }
_tstring GetSkyDrive() { return GetKnownFolder(FOLDERID_SkyDrive); }
_tstring GetOneDrive() { return GetKnownFolder(FOLDERID_OneDrive); }
_tstring GetSkyDriveDocuments() { return GetKnownFolder(FOLDERID_SkyDriveDocuments); }
_tstring GetSkyDrivePictures() { return GetKnownFolder(FOLDERID_SkyDrivePictures); }
_tstring GetSkyDriveMusic() { return GetKnownFolder(FOLDERID_SkyDriveMusic); }
_tstring GetSkyDriveCameraRoll() { return GetKnownFolder(FOLDERID_SkyDriveCameraRoll); }
_tstring GetSearchHistory() { return GetKnownFolder(FOLDERID_SearchHistory); }
_tstring GetSearchTemplates() { return GetKnownFolder(FOLDERID_SearchTemplates); }
_tstring GetCameraRollLibrary() { return GetKnownFolder(FOLDERID_CameraRollLibrary); }
_tstring GetSavedPictures() { return GetKnownFolder(FOLDERID_SavedPictures); }
_tstring GetSavedPicturesLibrary() { return GetKnownFolder(FOLDERID_SavedPicturesLibrary); }
_tstring GetRetailDemo() { return GetKnownFolder(FOLDERID_RetailDemo); }
_tstring GetDevice() { return GetKnownFolder(FOLDERID_Device); }
_tstring GetDevelopmentFiles() { return GetKnownFolder(FOLDERID_DevelopmentFiles); }
_tstring GetObjects3D() { return GetKnownFolder(FOLDERID_Objects3D); }
_tstring GetAppCaptures() { return GetKnownFolder(FOLDERID_AppCaptures); }
_tstring GetLocalDocuments() { return GetKnownFolder(FOLDERID_LocalDocuments); }
_tstring GetLocalPictures() { return GetKnownFolder(FOLDERID_LocalPictures); }
_tstring GetLocalVideos() { return GetKnownFolder(FOLDERID_LocalVideos); }
_tstring GetLocalMusic() { return GetKnownFolder(FOLDERID_LocalMusic); }
_tstring GetLocalDownloads() { return GetKnownFolder(FOLDERID_LocalDownloads); }
_tstring GetRecordedCalls() { return GetKnownFolder(FOLDERID_RecordedCalls); }
_tstring GetAllAppMods() { return GetKnownFolder(FOLDERID_AllAppMods); }
_tstring GetCurrentAppMods() { return GetKnownFolder(FOLDERID_CurrentAppMods); }
_tstring GetAppDataDesktop() { return GetKnownFolder(FOLDERID_AppDataDesktop); }
_tstring GetAppDataDocuments() { return GetKnownFolder(FOLDERID_AppDataDocuments); }
_tstring GetAppDataFavorites() { return GetKnownFolder(FOLDERID_AppDataFavorites); }
_tstring GetAppDataProgramData() { return GetKnownFolder(FOLDERID_AppDataProgramData); }
}