我使用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兼容?
答案 0 :(得分:6)
你正在混淆概念。在内核代码使用这些字符串时,所有路径字符串都是Unicode。 ShellExecuteEx的非Unicode版本(名为ShellExecuteExA)只是转换所有字符串并将SHELLEXECUTEINFOA结构转换为SHELLEXECUTEINFOW结构,然后调用真实 api函数ShellExecuteW()。您没有在代码中看到这些真实的标识符名称,因为宏在它们之间进行选择,但您当然可以在ShellAPI.h SDK #include文件中看到它们。
SEE_MASK_UNICODE
是一个相当神秘的选项,难以正确设置。我认为它与CreateProcess的CREATE_UNICODE_ENVIRONMENT
选项有关,表明新进程的环境可能包含Unicode字符。
路径字符串上的\\?\
前缀在Win32路径名和本机Windows内核路径名之间进行选择。 Win32是本机操作系统之上的API层。曾经有多个api层,OS / 2和Posix曾经被支持过但不再使用了。本机操作系统与Win32非常不同,它类似于VMS操作系统,大卫卡特勒在被微软雇用设计NT之前就已经开始工作了。没有像C:那样的东西,它只知道,\Device\Harddisk0\Partition0
。
API层在这两个世界之间进行转换。通过在路径字符串前加\\?\
前缀,您可以告诉Win32按原样使用路径字符串。然后,它使它获得本机路径字符串的功能,支持长达32726个字符的路径并绕过臭名昭着的Win32 MAX_PATH限制。暗示这些字符串是Unicode,这是所有内核都可以处理的。否则,ShellExecuteA将很乐意为您转换包含此前缀的8位编码字符串。
长话短说:它不是自动的。你必须自己编写前缀来明确地做到这一点。