Как получить путь к папке Program Files (не Program Files (x86)) из 32-битного процесса WOW?

Мне нужно получить путь к каталогу программных файлов native (а не WOW) из 32-битного процесса WOW.

Когда я передаю CSIDL_PROGRAM_FILES (или CSIDL_PROGRAM_FILESX86) в SHGetSpecialFolderPath, он возвращает путь к папке WOW (Program Files (x86)).

Я бы предпочел не использовать переменную окружения, если это возможно.

Я хочу сравнить некоторые значения, которые я читаю из реестра, если значения указывают на путь либо WOW, либо родной версии моего приложения, тогда мой код что-то делает, если не делает что-то еще. Чтобы выяснить, где ожидается версия родного и WOW моего приложения, мне нужно получить пути к "Program Files (x86)" и "Program Files".

Ответы

Ответ 1

Я ценю всю помощь и, особенно, предупреждения в этой теме. Тем не менее, мне действительно нужен этот путь, и именно так я получил его в конце:

(проверка ошибок удалена для ясности, использование на свой страх и риск и т.д.)

WCHAR szNativeProgramFilesFolder[MAX_PATH];
ExpandEnvironmentStrings(L"%ProgramW6432%", 
                       szNativeProgramFilesFolder, 
                       ARRAYSIZE(szNativeProgramFilesFolder);

Ответ 2

Позвольте мне процитировать Raymond Chen отличный блогпост по этому вопросу:

В 64-битной Windows запускаются 32-разрядные программы в слое эмуляции. Эта эмуляция слой имитирует архитектуру x86, виртуализация ЦП, файловой системы, реестр, окружающая среда переменные, системная информация функции, все это. Если 32-разрядный программа пытается посмотреть на систему, он увидит 32-битную систему. Для Например, если программа вызывает Функция GetSystemInfo, чтобы увидеть, что процессор работает, будет сказано что он работает на 32-битной процессор с 32-разрядным адресом пространства, в мире с 32-битным небом и 32-битные птицы в 32-битных деревьях.

И что точка эмуляции: Чтобы 32-битная программа была довольна моделирование 32-битного выполнения окружающая среда.

...

Вопрос: "Каков способ поиск программных файлов x64 каталог из 32-битного приложения?"

Ответ " Лучше работать с системой, а не с ней." Если вы 32-разрядная программа, тогда вы собирается бороться с эмулятора каждый раз, когда вы пытаетесь взаимодействовать с внешним миром. Вместо этого просто перекомпилируйте ваш установщик как 64-разрядный программа. Попросите 32-битный установщик обнаружить, что он работает на 64-битной и запустить 64-разрядный установщик вместо. 64-разрядный установщик не будет запускается в 32-битном слое эмуляции, поэтому когда он пытается скопировать файл или обновить раздел реестра, он увидит 64-битная файловая система и реальная 64-разрядная реестр.

Если вы все еще хотите это сделать, я рекомендую прочитать комментарии на этом блоге, поскольку они содержат некоторые полезные советы.

Ответ 3

Вы на правильном пути. Используйте KNOWNFOLDERID FOLDERID_ProgramFilesX64

Функция SHGetKnownFolderPath может использоваться для извлечения полного пути для данного KnownFolder.

Ответ 4

Это почти наверняка плохая идея, согласно недавнему сообщению из позорного Раймонда Чена. Подробнее см. здесь. В конце концов, я думаю, это можно сделать, но это тяжелая работа, и там почти наверняка более простой способ.

Microsoft построила слой эмуляции WOW, чтобы сделать вашу жизнь проще. Не тратьте впустую свое время и силы, сражаясь с ним: -).

Возможно, если вы сказали нам , почему вам нужен каталог программных файлов, отличных от WOW, мы могли бы помочь в дальнейшем.

Ответ 5

Мне понадобилось, чтобы получить папку программ x64 из Logonscript и использовать:

Dim oWshShell : Set oWshShell = CreateObject("WScript.Shell")
Dim sProgramDirPath : sProgramDirPath = 
    oWshShell.ExpandEnvironmentStrings("%ProgramW6432%")

WScript.Echo sProgramDirPath

Ответ 6

Лучший и универсальный способ получить путь к "Программным файлам" - это запросить его из реестра:

64-битный процесс может запрашивать: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir для получения "C:\Program Files" HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ProgramFilesDir для получения "C:\Program Files (x86)"

32-бит-процесс (Wow64) может запрашивать: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir для получения "C:\Program Files (x86)" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir с опцией KEY_WOW64_64KEY! для получения "C:\Program Files"

Псевдо-код:

OpenKey(hKey, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ | KEY_WOW64_64KEY);
QueryStringValue(hKey, L"ProgramFilesDir", sValue);