You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求Windows下获取文件真实大小写敏感路径的函数(游戏Lua绑定场景)

实现Windows下路径大小写敏感验证的方案

要让Windows环境下的文件操作和Linux保持一致的大小写敏感性,核心是获取文件系统中存储的真实路径大小写形式,再与用户输入的路径对比——若不匹配则拒绝操作。以下是几种可行的实现方式:

方法1:用FindFirstFileW遍历路径组件验证

FindFirstFileW会返回文件系统中实际存储的文件名(包含正确大小写),我们可以拆分路径的每个目录/文件组件,逐层查询真实名称:

#include <windows.h>
#include <string>
#include <vector>
#include <algorithm>

std::wstring GetRealCasePath(const std::wstring& inputPath) {
    std::wstring realPath;
    std::wstring currentDir = L".\\";
    std::vector<std::wstring> components;

    // 拆分路径组件(处理绝对/相对路径)
    size_t pos = 0;
    std::wstring remaining = inputPath;
    if (!inputPath.empty() && inputPath[1] == L':') {
        realPath = inputPath.substr(0, 2);
        currentDir = realPath;
        remaining = inputPath.substr(2);
    }
    while ((pos = remaining.find(L'\\')) != std::wstring::npos) {
        components.push_back(remaining.substr(0, pos));
        remaining = remaining.substr(pos + 1);
    }
    if (!remaining.empty()) {
        components.push_back(remaining);
    }

    // 逐层查询真实名称
    for (const auto& comp : components) {
        WIN32_FIND_DATAW findData;
        HANDLE hFind = FindFirstFileW((currentDir + L"\\" + comp).c_str(), &findData);
        if (hFind == INVALID_HANDLE_VALUE) {
            return L""; // 路径不存在,返回空
        }
        FindClose(hFind);
        realPath += L"\\" + std::wstring(findData.cFileName);
        currentDir = realPath;
    }

    return realPath;
}

使用时,将用户输入的路径转换为宽字符串,调用此函数得到真实路径,再与原输入对比(区分大小写):

std::wstring input = L"Foo.txt";
std::wstring realPath = GetRealCasePath(input);
if (realPath.empty() || input != realPath.substr(realPath.find_last_of(L'\\') + 1)) {
    // 文件名大小写不匹配,拒绝操作
    // 比如返回Lua错误,或让文件打开失败
}

方法2:用GetFinalPathNameByHandleW获取完整真实路径

通过CreateFileW打开文件/目录获取句柄,再调用此函数获取文件系统存储的真实路径:

#include <windows.h>
#include <string>

std::wstring GetRealFullPath(const std::wstring& inputPath) {
    HANDLE hFile = CreateFileW(inputPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
    if (hFile == INVALID_HANDLE_VALUE) {
        return L"";
    }

    wchar_t buffer[MAX_PATH];
    DWORD len = GetFinalPathNameByHandleW(hFile, buffer, MAX_PATH, VOLUME_NAME_DOS);
    std::wstring realPath;
    if (len > 0 && len <= MAX_PATH) {
        realPath = buffer;
        // 去掉可能的\\?\前缀
        if (realPath.substr(0, 4) == L"\\\\?\\") {
            realPath = realPath.substr(4);
        }
    }

    CloseHandle(hFile);
    return realPath;
}

同样,对比真实路径和用户输入的路径,若大小写不一致则触发错误。

为什么GetFullPathName不适用?

GetFullPathName仅负责将相对路径转换为绝对路径,不会查询文件系统的真实文件名存储形式,返回的路径大小写与用户输入完全一致,无法满足验证需求。

集成到Lua绑定的思路

在Lua绑定的文件操作接口(如打开文件、查询路径)中,先调用上述函数获取真实路径:

  • 若路径不存在:直接返回错误
  • 若路径存在但大小写与用户输入不匹配:同样返回错误,模拟Linux下的行为

这样就能确保mod在Windows开发时,一旦依赖大小写不敏感特性就会立即报错,避免到Linux环境崩溃。

内容的提问来源于stack exchange,提问作者MyNameIsTrez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:47:44