int SearchFile(string path, int* num, map<string, string>* _path)
{
string buffer = "";
buffer = path + "\\*.*";
_WIN32_FIND_DATAA pNextInfo;//保存文件信息
HANDLE hFile = 0;
hFile = FindFirstFileA(buffer.c_str(), &pNextInfo);
int a = GetLastError();
if (a && (a != 2)) {
string errorpath = path+ " : " + to_string(a);
WriteErrorToLog(errorpath);
}
if (hFile != INVALID_HANDLE_VALUE)//
{
do
{
if (pNextInfo.cFileName[0] == '.' || pNextInfo.cFileName[0] == '..')//过滤.和..
continue;
//dwFileAttributes值是可以一位或多位的,不好直接使用"=="来判断
if (pNextInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)//判断是否为文件夹
{
buffer = path + "\\" + pNextInfo.cFileName;//将文件夹追加到目录,成为下一级要搜索目录
SearchFile(buffer, num, _path);//递归
}
ULARGE_INTEGER ulFileSize;
//求得文件的大小
ulFileSize.LowPart = GetCompressedFileSizeA((pNextInfo.cFileName), &(pNextInfo.nFileSizeHigh));
__int64 creattime = *(__int64*)&(pNextInfo.ftCreationTime);//将FILETIME转换成
__int64 writetime = *(__int64*)&(pNextInfo.ftLastWriteTime);
//将文件绝对路径,创建时间,修改时间,文件大小拼接
string str = path + "\\" + pNextInfo.cFileName + to_string(creattime) + to_string(writetime) + to_string(ulFileSize.LowPart);
//遍历结束一个文件路径进行++
//将文件的属性全部存到map中
//求出exe,dll文件
string str_ed = pNextInfo.cFileName;
int size = str_ed.size();
if (size > 3) {
string str_1 = str_ed.substr(size - 3);
//|| strcmp(str_1.c_str(), "exe") == 0
//|| strcmp(str_1.c_str(), "exe") == 0 || strcmp(str_1.c_str(), "bat") == 0
if (strcmp(str_1.c_str(), "dll") == 0) {
string _md5 = md5(str);
buffer = path + "\\" + pNextInfo.cFileName;
(*num)++;
(*_path).insert(pair<string, string>(buffer, _md5));//存储到map中
}
}
} while (FindNextFileA(hFile, &pNextInfo));//遍历文件
}
FindClose(hFile);
return 0;
}
害,在查了好多资料还有在网上查问题后,发现了三个问题,一是重定向问题,二是权限问题,三是函数使用,判断出错。
1.重定向问题:是因为在在win64下,system32会重定向到SysWOW64,因此在遍历的时候后出现错误,解决的方法是在你进行遍历的时候加上下面这段代码。
PVOID OldValue = NULL;
//关闭系统重定向
if (Wow64DisableWow64FsRedirection(&OldValue)) {
//查找指定路径
hFile = FindFirstFileA(buffer.c_str(), &pNextInfo);
if (FALSE == Wow64RevertWow64FsRedirection(OldValue))
return NULL;
}
2.权限问题:提升权限,反正我是将exe程序注册成了服务
3.函数使用问题:
在我上面的代码我的strcmp()在进行判断时他区分了大小写,因此在遍历文件时才会出现遍历不完全,dll,exe等文件有的后缀时大写的,可以使用stricmp()函数进行比较。
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt");
//读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录
system("dir /b /ad c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
如果嫌system黑窗口一闪,将system("...")替换为WinExec("cmd /c ...",SW_HIDE);