Как 32-разрядное приложение может найти местонахождение 64-разрядного каталога программных файлов в Windows Vista 64-бит?

StackOverflow https://stackoverflow.com/questions/1958881

  •  21-09-2019
  •  | 
  •  

Вопрос

Я борюсь с проблемой того, как определить местоположение 64-разрядного каталога программных файлов на 64-битной Windows Vista из 32-битного приложения.

Вызовы в SHGetKnownFolderPath(FOLDERID_ProgramFilesX64) Не возвращай ничего. А MSDN статья Известно также заявляет, что этот конкретный звонок с FOLDERID_ProgramFilesX64 не поддерживается для 32-битного приложения.

Я хотел бы избежать максимально возможного жесткого кодирования пути в «C: Program Files». Делать что -то вроде GetWindowsDirectory(), Извлечение диска из возвращаемого значения и добавление « Program Files» к нему также не привлекательно.

Как 32-разрядное приложение может правильно получить местоположение папки от 64-битной Windows Vista?

Фон

В нашем приложении есть сервисный компонент, который должен запускать другие процессы на основе запросов из компонента, специфичного для пользователя. Запущенные приложения могут быть 32-битными или 64-битными. Мы делаем это через CreateProcessAsUser() пропустив токен от инициирования процесса пользовательской серии. Для вызова CreateProcessAsUser, мы создаем блок среды через CreateEnvironmentBlock() API Проблема в том, что CreateEnvironmentBlock(), используя токен приложения пользователя-сеанса, создает блок с ProgramW6432 = "C: Program Files (x86)", что является проблемой для 64-битных приложений. Нам нужно переопределить его с правильным значением.

Это было полезно?

Решение

Как вы упомянули, использование Shget KnowledFolderPath из 32-разрядного приложения не будет работать в 64-разрядной операционной системе. Это потому, что эмуляция WOW64 действует.

Вы можете использовать Regopenkeyex Переходя в флаге KEY_WOW64_64KEY а затем прочитайте каталог программных файлов из реестра.

Место в реестре:

Hkey_local_machine Software Microsoft Windows CurrentVersion

Вы заинтересованы в значении строки:

Programfilesdir

Другие советы

Если вы внимательно прочитаете эту страницу, вы увидите, что FOLTERID_PROGRAMFILESX64 поддерживается для 32-битных приложений на 64-битной ОС. Это не поддерживается на 32-битной ОС, что имеет смысл.

FOLDERID_PROGRAMFILESX64 поддерживается ...

MSDN говорит, что это поддерживается, но документ Microsoft "WOW64" Best Practices говорится, что это не так. Видеть http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/wow64_bestprac.docx

Цитировать:

• Некоторые переменные работают, только если процесс составляет 64-битный. Например, fotherid_programfilesx64 не работает для 32-разрядных вызывающих абонентов. В версиях Windows раньше, чем Windows 7, % ProgramW6432 % не работали в контексте 32-битных процессов. Приложение должно определить, работает ли он в 64-битном процессе, прежде чем использовать эти переменные.

Под Windows 7 X64, запустив 32-разрядное приложение в отладчике Visual Studio, я также получаю код возврата 0x80070002 (и нулевой указатель). Запуск того же кода, скомпилируемого как 64-битный, возвращает значение s_ok, и путь правильно заполнен.

Я использовал взлом реестра, как указано выше, так как я не могу найти другой обходной путь.

Вы также можете запросить переменную среды ProgramW6432. Анкет Очевидно, что он существует только в 64-разрядных Windows, но он должен вернуть реальный 64-разрядный каталог программных файлов, и, похоже, определяется как для 64-битных, так и для 32-разрядных программ. По крайней мере, это сработало для меня (C#, GetEnvironmentVariable)...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top