Разрешить переменную PROGRAMFILES из 32-битного приложения в ОС Win64?

Как объяснено в WOW64, подробности реализации, переменная %PROGRAMFILES%,

  • в 32-битном процессе в 64-битной ОС Windows разрешается в C:\Program Files (x86)

  • в 64-битном процессе в 64-битной ОС Windows разрешается в C:\Program Files

Вы можете проверить это, например. с программой Delphi 10.1, скомпилированной как с 32-разрядной целевой платформой Windows, так и с 64-разрядной целевой платформой Windows:

MyShellExecute('%PROGRAMFILES%');

Итак, из 32-битного приложения Delphi, выполненного в 64-битной ОС Windows, как я могу получить ОБА:

  • каталог ProgramFiles для 32-битных программ (C:\Program Files (x86))

  • каталог ProgramFiles для 64-битных программ (C:\Program Files)


person user1580348    schedule 11.10.2017    source источник
comment
Я не могу это проверить, так как у меня нет функции MyShellExecute, насколько я знаю.   -  person Rudy Velthuis    schedule 12.10.2017
comment
@Rudy - Вероятно, это потому, что вы забыли адаптировать местоимение; вы должны попробовать His/HerShellExecute. <грамм>   -  person Sertac Akyuz    schedule 13.10.2017
comment
@Sertac: Ах, да, я забыл. <грамм>   -  person Rudy Velthuis    schedule 13.10.2017


Ответы (1)


Используйте следующие переменные среды:

  • ProgramW6432 для получения каталога файлов 64-битной программы.
  • ProgramFiles(x86) для получения каталога файлов 32-битной программы.

Они возвращают одинаковые значения как в 32-битных, так и в 64-битных процессах.

Конечно, полагаться на переменные окружения всегда немного неудобно. Ваш родительский процесс всегда может изменить эти переменные перед созданием вашего процесса.

Чтобы сделать вашу программу более надежной, вы должны использовать известные идентификаторы папок вместо этого. Используйте FOLDERID_ProgramFilesX64 и FOLDERID_ProgramFilesX86.

person David Heffernan    schedule 11.10.2017
comment
FOLDERID_ProgramFilesX64 не поддерживается для 32-разрядных приложений, работающих в 64-разрядных операционных системах. Попытка использовать FOLDERID_ProgramFilesX64 в этой ситуации приводит к ошибке. - person user1580348; 11.10.2017
comment
Да. Это задокументировано в темах, на которые я ссылался. Из 64-битного процесса вы можете найти 32-битную папку. - person David Heffernan; 11.10.2017
comment
Обычно только установщики заботятся о расположении этих папок, так что это не является большим ограничением. - person David Heffernan; 11.10.2017
comment
У меня возникла ситуация, когда ShellLink, указывающий на файл программы в папке для 64-битных программ, разрешается на неправильный путь в папке для 32-битных программ при выполнении в 32-битной программе в 64-битной Windows. - person user1580348; 11.10.2017
comment
Это звучит странно. Интересно, как решается ссылка. Впрочем, это другая тема. Я думаю, что ответил на конкретный вопрос здесь. - person David Heffernan; 11.10.2017
comment
@user1580348: Попытка использовать FOLDERID_ProgramFilesX64 в [32-битном приложении] приводит к ошибке — ваше приложение должно определить, является ли это 32-битным процессом, работающим в 32-битной или 64-битной ОС, или запущенным как 64-битный процесс. , а затем использовать соответствующий KNOWNFOLDERID для своих нужд. При компиляции для 32-битной версии используйте IsWow64Process(), чтобы узнать, работаете ли вы внутри Wow64 или нет. - person Remy Lebeau; 11.10.2017
comment
Для таких случаев я использую $IFDEF. Компилятор лучше знает, что он генерирует. - person Rudy Velthuis; 12.10.2017
comment
Компилятор @rudy не может определить, работаете ли вы в 32-битной или 64-битной системе. - person David Heffernan; 12.10.2017
comment
@ Дэвид: это правда. Но доступ к FOLDERID_ProgramFilesX64 из 32-битного приложения запрещен. Компилятор может мне в этом помочь. Также можно проверить результат GetSpeicalFolderID (или любой подобной функции). - person Rudy Velthuis; 12.10.2017