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

如何向仅支持ANSI的C++函数传入含Unicode字符的文件路径?

Detours库ANSI函数处理Unicode路径的问题

摘要

尝试将包含Unicode(UTF-16)字符的DLL路径传入Detours库4.0.1版本中仅支持ANSI字符的DetourCreateProcessWithDllEx和DetourCreateProcessWithDlls函数,遇到路径兼容问题。

问题详情

这两个函数的lpDllName和*rlpDlls参数类型为LPCSTR,不支持宽字符。官方说明原因是“导入表没有宽字符版本”,相关议题已锁定,需寻找替代方案。

通过withdll示例代码测试发现,失败根源在LoadLibraryExA调用阶段——该函数会提前检查DLL导出项,若调用失败,后续Detours函数大概率也会失败。虽然LoadLibraryExW能通过检查,但失败会延迟到Detours函数调用阶段。

目前观察到部分简单Unicode路径(如E:\test\Chäröcter Teßt或E:\test\Bjørn)可正常工作,但包含复杂Unicode字符的路径(如E:\test\Bölükbaşı)会失败:LoadLibraryExA返回错误码126(“找不到指定模块”),Detours调用返回错误码3(“系统找不到指定路径”)。

测试代码

以下是从withdll示例中提取的精简测试代码(可移除Detours代码,仅通过LoadLibraryExA验证问题):

#include <windows.h>
#include <detours.h>
#include <strsafe.h>

int CDECL main(int argc, char** argv)
{
    LPCSTR rpszDllRaw = "detoursSimpleDll64.dll"; // 同目录下存在该文件及32位版本
    LPCSTR szExe = "HelloWorld.exe";              // 同目录下存在该文件

    LPCSTR rpszDllOut;
    CHAR szDllPath[1024];
    PCHAR pszFilePart = NULL;

    if (!GetFullPathNameA(rpszDllRaw, ARRAYSIZE(szDllPath), szDllPath, &pszFilePart)) {
        printf("Error - GetFullPathNameA: %s is not a valid path name\n", rpszDllRaw);
        return 9002;
    }

    DWORD c = (DWORD)strlen(szDllPath) + 1;
    PCHAR psz = new CHAR[c];
    StringCchCopyA(psz, c, szDllPath);
    rpszDllOut = psz;

    HMODULE hDll = LoadLibraryExA(rpszDllOut, NULL, DONT_RESOLVE_DLL_REFERENCES);

    if (hDll == NULL) {
        printf("Error - LoadLibraryExA: %s failed to load (error %ld).\n", rpszDllOut, GetLastError());
        return 9003;
    }
    else {
        printf("LoadLibraryExA succeeded for %s\n", rpszDllOut);
    }


    // Detours相关代码开始
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    CHAR szCommand[2048];
    CHAR szFullExe[1024] = "\0";
    PCHAR pszFileExe = NULL;

    DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;
    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    si.cb = sizeof(si);

    szCommand[0] = L'\0';

    SetLastError(0);
    SearchPathA(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe);


    if (!DetourCreateProcessWithDllExA(szFullExe[0] ? szFullExe : NULL, szCommand,
        NULL, NULL, TRUE, dwFlags, NULL, NULL,
        &si, &pi, rpszDllOut, NULL)) {
        DWORD dwError = GetLastError();
        printf("DetourCreateProcessWithDllEx failed: %ld\n", dwError);
        ExitProcess(9009);
    }

    printf("DetourCreateProcessWithDllEx succeeded for %s and %s\n", szFullExe, rpszDllOut);


    ResumeThread(pi.hThread);

    WaitForSingleObject(pi.hProcess, INFINITE);

    DWORD dwResult = 0;
    if (!GetExitCodeProcess(pi.hProcess, &dwResult)) {
        printf("GetExitCodeProcess failed: %ld\n", GetLastError());
        return 9010;
    }
    dllPathFinal = NULL;
    delete dllPathFinal;


    return dwResult;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:37:28