【问题标题】:Case Sensitive Directory Path in WindowsWindows 中区分大小写的目录路径
【发布时间】:2019-10-12 18:19:24
【问题描述】:

我已经查看了询问目录/文件名在 Windows 环境中是否区分大小写的问题/答案,以及讨论需要区分大小写搜索的问题/答案 [通常在 Python 中,而不是 C 中],所以我想我了解基本事实,但没有一篇帖子包含我的特定应用程序架构,以及我解决问题时遇到的问题。 所以,让我简要解释一下我所说的应用程序架构。该应用程序的核心是使用 Adob​​e AIR 构建的。是的,这意味着大部分 U/I 都涉及 Flex 框架,但我需要帮助的文件处理问题不依赖于应用程序的 Flex U/I 部分。 当我试图处理一个非常大的递归目录结构列表时,我通过一种行为良好的机制使用低级 C 运行时 API,AIR 为需要访问主机的本机环境的情况提供了这种机制。

我使用的函数套件是 FindFileFirst、FindFileNext 和 FindClose。如果我编写一个独立的测试程序,它会很好地列出目录、子目录和文件。目录和文件的大小写正确显示——就像它们在 Windows 资源管理器中正确显示一样,或者使用 dir 命令。

但是,如果我通过 Adob​​e ANE 界面启动完全相同的功能,我会收到完全相同的输出,但所有目录名称都将缩减为小写。

现在,我要澄清的是,当这段代码作为原生扩展执行时,它不会将数据传回 AIR,而是直接将结果输出到一个完全在 CRT 世界中打开和关闭的文件中,所以我们不是在谈论通过在两个不同世界之间传递文本或字节数组而造成的任何形式的通信混乱。

没有用大量无关代码将这个论坛塞满,我认为可以帮助任何能够帮助我的人是这些 sn-ps:

// This is where the output gets written.
FILE* textFile = _wfopen (L"Peek.txt", L"wt,ccs=UTF8");

WIN32_FIND_DATAW fdf;
HANDLE find = NULL;
wchar_t fullPath[2048];

// I am just showing the third argument as a literal to exemplify
// what, in reality is passed into the recursively-called function as
// a variable.
wsprintf (fullPath, L"\\\\?\\%ls\\*.*", L"F:\\");
hFind = FindFirstFile (fullPath, &fdf);

// After checking for success there appears a do..while loop
// inside which there is the expected check for the "." and ".."
// pseudo directories and a test of fdf.dwFileAttributes for
// file versus sub-directory.
// When the NextFile is a file a function is called to format
// the output in the textFile, like this:

fwprintf (textF, L"%ls\t%ls\t%2.2x\t%4d/%02d/%02d/%02d/%02d/%02d  \t%9ld.\n",
     parentPath, fdf.cFileName,
    (fdf.dwFileAttributes & 0x0f),
    st.wYear, st.wMonth, st.wDay,
    st.wHour, st.wMinute, st.wSecond,
    fSize);

此时 parentPath 将是一个连接的宽字符串,并且 其他文件属性将是显示的类型。

所以,总结一下:如果我只是编写一个独立的测试,那么所有这些代码都可以完美运行。但是,当代码作为从 Adob​​e ANE 调用的任务运行时,所有子目录部分的名称都被缩减为小写。我已经测试了文件类型属性的每一种组合——二进制和文本以及编码——UTF-8 和 UTF-16LE,但无论我选择什么配置,结果都是一样的:独立 API 提供大小写正确的字符串,运行作为从 AIR 调用的 dll 中的任务,相同的 API 仅提供小写字符串。

【问题讨论】:

  • 您应该使用调试器来检查FindFirst* 函数在这两种情况下返回的内容。如果在 ANE 情况下名称都是小写的,那么 ANE 会以某种方式拦截 FindFirst* 调用。
  • 很难想象 ANE 会修补 FindFirst/NextFile(),但听起来就是这样。可能是处理 Unix 和 Windows 之间差异的一个技巧。不使用 `\\?\` 前缀可能会产生影响。 SHGetFileInfo() 可能会提供一种解决方法。
  • 有什么问题?

标签: c ane


【解决方案1】:

首先,感谢 Ogilvie 和 Passant 先生提供的有用建议。

其次,我很抱歉作为一个非常罕见的访问者并不真正了解这里的协议。如果我应该将任一响应标记为有帮助并因此是正确的,请让这些词至少反映这一事实。

我提供了一个通过上述建议发现的答案。

A.我发现了几个工具可以帮助我处理 .exe 和 .dll 文件的内容。我应该添加一些不属于原始帖子的细节:我故意使用 mingw-w64 工具链而不是 Visual Studio 来进行这项开发工作。因此,事实证明,ldd 和 dumpbin 都帮助我了解这两个略有不同的构建环境是否可能会给我留下不同的依赖关系。

B.当我看到一个输出包含对 FindFirstFileExW 的引用时,我曾经尝试过该函数以解决我认为的问题,我想我可能找到了导致不同结果的原因。在事件中,这只是一个红鲱鱼,我并不是要以我低水平的经验和理解来浪费论坛的时间,但将这种故障排除方法作为对其他人的可能帮助似乎很有用.

C.那么问题出在哪里?实际上,递归目录搜索的独立实现和 ANE 集成实现之间的代码存在细微差别。在生产 ANE 用例中,有逻辑对返回的结果应用过滤级别。实际的应用程序允许用户通过询问除了文件名字符串本身之外的部分父字符串来限定对重复文件的搜索。

在一个角落条件下,过滤器可能区分大小写或不区分大小写,我在使用 _wcslwr 时错误地认为该函数的行为与 AIR/Actionscript3 中提供的字符串处理方法一样好,符合 Unicode。我没有注意到该函数实际上将原始字符串替换为小写。

罪魁祸首是用户错误,而不是 Adob​​e 的本机扩展互操作性对非标准 CRT 内核函数的任何不良链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2011-10-06
    • 2021-11-16
    相关资源
    最近更新 更多