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

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

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

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

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

Фон

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

Ответы [ 4 ]

8 голосов
/ 24 декабря 2009

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

Однако вы можете использовать RegOpenKeyEx , передав флаг KEY_WOW64_64KEY, а затем прочитать каталог программных файлов из реестра.

Местоположение в реестре:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion

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

ProgramFilesDir

1 голос
/ 24 декабря 2009

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

0 голосов
/ 20 августа 2014

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

0 голосов
/ 29 июля 2010

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 (и указатель NULL). Выполнение того же кода, скомпилированного как 64-битный, возвращает значение S_OK и путь правильно заполнен.

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

...