好的,这让我发疯了。我正在编写一个简单的程序,沿着目录树查看我的驱动器上所有文件的大小。很温顺的东西。
但我注意到我没有得到我预期的答案。结果我的代码是跳过一些目录。首先,这是我的代码的(简化)版本:
#include <stdio.h>
#include <Windows.h>
int main()
{
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(L"c:\\Windows\\System32\\wbem\\*.*", &fd);
if (h != INVALID_HANDLE_VALUE)
{
BOOL b;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
printf("d: %S\n", fd.cFileName);
//else
// printf("f: %S\n", fd.cFileName);
b = FindNextFile(h, &fd);
} while (b != FALSE);
FindClose(h);
}
}
我得到的输出几乎是你所期望的:
d: .
d: ..
d: AutoRecover
d: en-US
d: Logs
d: Repository
d: tmf
d: xml
但是,从c:\ Windows \ System32 \ wbem中的命令提示符,dir /ad
给了我:
06/15/2016 07:20 PM <DIR> .
06/15/2016 07:20 PM <DIR> ..
04/14/2016 05:40 PM <DIR> AutoRecover
03/24/2011 03:52 PM <DIR> en-US
07/13/2009 06:34 PM <DIR> Logs
07/13/2009 09:08 PM <DIR> MOF
02/20/2017 10:32 PM <DIR> Performance
02/23/2017 03:59 AM <DIR> Repository
07/13/2009 06:36 PM <DIR> tmf
07/13/2009 07:20 PM <DIR> xml
0 File(s) 0 bytes
10 Dir(s) 171,203,104,768 bytes free
仔细检查发现我的输出中未列出Performance
和MOF
目录。咦?
显然这些目录有些不同。但是什么?
dir
输出,我们可以看到它们不是联结。我很难过。我甚至跑到chkdsk /f
以查看我的目录表是否搞砸了。除了一些Cleaning up 472 unused index entries from index $SII of file 0x9. Cleaning up 472 unused index entries from index $SDH of file 0x9.
之外,它没有找到任何东西。
我尝试过使用各种选项的FindFileEx,但我仍然无法显示这些目录。
我想不出还有什么可尝试的。什么会导致这些目录显示dir
但不显示FindFile
? (更重要的是)如何让它们出现在FindFile中?
FWIW:
答案 0 :(得分:3)
您的代码正在尝试访问64位System32
文件夹。
我猜你的代码被编译为32位,因此你实际上会因为File System Redirector而访问32位SysWOW64
文件夹。在我的Win7 x64计算机上,缺少的文件夹(MOF
和Performance
)仅存在于64位System32\wbem
文件夹中,但不存在于32位SysWOW64\wbem
文件夹中。
如果32位代码想要访问64位System32
文件夹,则必须使用WOW64的特殊Sysnative
别名来避免重定向,例如:
HANDLE h = FindFirstFile(L"c:\\Windows\\Sysnative\\wbem\\*.*", &fd);
使用IsWow64Process()
了解您的代码是否在WOW64模拟器中运行。
话虽如此,您也不应该对c:\\Windows
路径进行硬编码。并非所有用户都将Windows安装到该路径。请改用GetWindowsDirectory()
,SHGetFolderPath(CSIDL_WINDOWS)
或SHGetKnownFolderPath(FOLDERID_Windows)
来获取实际路径。
尝试更像这样的事情:
bool IsRunningInWow64()
{
#ifndef _WIN64
BOOL bIsWow64 = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64)
return true;
#endif
return false;
}
...
WCHAR szMask[MAX_PATH];
if (IsRunningInWow64())
{
// Must be a 32-bit process running on a 64-bit system.
// Use the 'Sysnative' alias...
GetWindowsDirectory(szMask, MAX_PATH);
// or: SHGetFolderPath(..., CSIDL_WINDOWS, ...);
// or: SHGetKnownFolderPath(FOLDERID_Windows, ...);
PathAppend(szMask, L"Sysnative");
}
else
{
// Must be either:
// - A 32-bit process running on a 32-bit system.
// - A 64-bit process running on a 64-bit system.
// Use the standard 'System32' path...
GetSystemDirectory(szMask, MAX_PATH);
// or: SHGetFolderPath(..., CSIDL_SYSTEM, ...);
// or: SHGetKnownFolderPath(FOLDERID_System, ...);
}
PathAppend(szMask, L"wbem");
PathAppend(szMask, L"*.*");
HANDLE h = FindFirstFile(szMask, &fd);