-1

我曾经ShellExecuteEx()调用一个可执行文件。以下是我为SHELLEXECUTEINFO结构设置的参数。

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS|SEE_MASK_UNICODE;// Set Unicode Flag
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpParameters = TEXT ("/s");
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOWNORMAL;
ShExecInfo.hInstApp = NULL;
ShExecInfo.lpFile = TEXT ( ".\\bin\\x86\\installerx86.exe" ); 

ShExecInfo.fMask是为 Unicode 设置的,但没有ShExecInfo.lpFile"\\?\". 在这种情况下,我的代码是否与 Unicode 兼容?

4

1 回答 1

6

你在混淆概念。到内核​​代码使用这些字符串时,所有路径字符串都是 Unicode。非 Unicode 版本的 ShellExecuteEx(名为 ShellExecuteExA)只是简单地翻译所有字符串并将 SHELLEXECUTEINFOA 结构转换为 SHELLEXECUTEINFOW 结构,然后调用真正的api 函数 ShellExecuteW()。由于宏在它们之间进行选择,因此您不会在代码中看到这些真正的标识符名称,但您当然可以在 ShellAPI.h SDK #include 文件中看到它们。

SEE_MASK_UNICODE是一个相当神秘的选项,很难正确设置。我觉得CREATE_UNICODE_ENVIRONMENT和CreateProcess的选项有关,说明新进程的环境可能包含Unicode字符。

路径字符串上的\\?\前缀在 Win32 路径名和本机 Windows 内核路径名之间进行选择。Win32 是原生操作系统之上的 API 层。曾经有多个 api 层,OS/2 和 Posix 曾经支持但不再使用。本机操作系统与 Win32 非常不同,它类似于 VMS 操作系统,这是 David Cutler 在被微软聘用设计 NT 之前所做的工作。没有 C: drive there 这样的东西,它只知道,比如说,\Device\Harddisk0\Partition0

API 层在这两个世界之间进行转换。通过在路径字符串前加上前缀,\\?\您可以告诉 Win32 按原样使用路径字符串。然后使其获得本机路径字符串的功能,支持长达 32726 个字符的路径并绕过臭名昭著的 Win32 MAX_PATH 限制。这些字符串是 Unicode 是隐含的,这就是内核可以处理的所有内容。ShellExecuteA 否则会很高兴地为您转换包含此前缀的 8 位编码字符串。

长话短说:它不是自动的。您必须通过自己编程前缀来明确地做到这一点。

于 2012-09-20T10:29:03.190 回答