Я борюсь с проблемой того, как определить местоположение 64-разрядного каталога Program Files на 64-разрядном Windows Vista из 32-разрядного приложения.
Вызовы к SHGetKnownFolderPath(FOLDERID_ProgramFilesX64)
ничего не возвращайте. В статье MSDN KNOWNFOLDERID также говорится что этот конкретный вызов с FOLDERID_ProgramFilesX64
не поддерживается для 32-разрядного приложения.
Я хотел бы избежать как можно больше жесткое кодирование путь к "C:\Program Files". Выполнение чего-то как GetWindowsDirectory()
, извлечение диска от возвращаемого значения и добавления "\Program Файлы" к нему не обращается также.
Как 32-разрядное приложение может правильно получить местоположение папки от 64-разрядного Windows Vista?
Наше приложение имеет сервисный компонент, который, как предполагается, запускает другие процессы на основе запросов от определенного для сеанса пользователя компонента. Запущенные приложения могут быть 32-разрядными или 64-разрядными. Мы делаем это через CreateProcessAsUser()
путем передачи в маркере от процесса сеанса пользователя инициирования. Для вызова к CreateProcessAsUser
, мы создаем блок среды через CreateEnvironmentBlock()
API. Проблема - это CreateEnvironmentBlock()
, использование маркера приложения сеанса пользователя, создает блок с ProgramW6432 = "C:\Program Files (x86)", который является проблемой для 64-разрядных приложений. Мы должны переопределить его с собственным значением.
Как вы уже упоминали, использование SHGetKnownFolderPath из 32-битного приложения не будет работать на 64-битной операционной системе. Это связано с тем, что действует эмуляция Wow64. Однако вы можете использовать RegOpenKeyEx, передавая флаг KEY_WOW64_64KEY
, а затем читать каталог программных файлов из реестра.
Местоположение в реестре:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
Вас интересует значение строки:
ProgramFilesDir
Если внимательно прочитать эту страницу, то можно увидеть, что FOLDERID_ProgramFilesX64 поддерживается для 32-битных приложений на 64-битной операционной системе. На 32-битной ОС это НЕ поддерживается, что вполне логично.
.FOLDERID_ProgramFilesX64 поддерживается ...
MSDN утверждает, что поддерживается, но в документе с рекомендациями Microsoft "WOW64" говорится, что это не так. См. http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx
Цитата:
• Некоторые переменные работают, только если процесс 64-битный. Например, FOLDERID_ProgramFilesX64 не работает для 32-разрядных вызывающих абонентов. В версиях Windows до Windows 7% ProgramW6432% не работал в контексте 32-битных процессов. Приложение должно определить, работает ли оно в 64-битном процессе, прежде чем использовать эти переменные.
В Windows 7 x64 при запуске 32-разрядного приложения в отладчике Visual Studio я также получаю код возврата 0x80070002 (и нулевой указатель). Выполнение того же кода, скомпилированного как 64-битная, возвращает значение S_OK, и путь правильно заполнен.
Я использовал взлом реестра, как указано выше, так как я не могу найти другого обходного пути.