Чтобы открыть диалоговое окно UAC в Vista при записи в куст реестра HKLM, мы предпочитаем не использовать Win32 Registry API, так как при отсутствии разрешений Vista нам придется перезапустить все наше приложение с правами администратора. Вместо этого мы проделываем такой трюк:
ShellExecute(hWnd, "runas" /* display UAC prompt on Vista */, windir + "\Reg", "add HKLM\Software\Company\KeyName /v valueName /t REG_MULTI_TZ /d ValueData", NULL, SW_HIDE);
Это решение отлично работает, кроме того, что наше приложение является 32-битным и запускает команду REG.EXE, как это было бы 32-битное приложение, использующее уровень совместимости WOW! :( Если REG.EXE запускается из командной строки, он правильно работает в 64-битном режиме. Это важно, потому что, если он запускается как 32-битное приложение, ключи реестра окажутся в неправильном месте из-за отражение реестра.
Итак, есть ли способ запустить 64-битное приложение программно из 32-битного приложения и не запускать его с использованием подсистемы WOW64, такой как его родительский 32-битный процесс (то есть суффикс «*» в диспетчере задач)?





Думали ли вы о создании небольшого «вспомогательного» приложения для обновления реестра? Если вы скомпилируете его для 64-битной версии и включите манифест, в котором указано, что для этого требуются права администратора, он будет покрывать обе базы для вас.
Существуют API-интерфейсы для определения «разрядности» операционной системы, в которой вы работаете, поэтому вы, вероятно, можете скомпилировать и RegistryUpdate32.exe, и RegistryUpdate64.exe и вызвать соответствующий.
Будет ли запущена 32-битная или 64-битная собственная (неуправляемая) программа, зависит исключительно от исполняемого файла. Есть две копии reg.exe в C: \ Windows \ System32 (64-разрядная версия) и C: \ Windows \ SysWOW64 (32-разрядная версия). Поскольку вы не указываете путь, вы получаете то, что появляется первым в переменной среды PATH, которая является 32-битной версией для 32-битного процесса.
Вам действительно следует выделить эту функцию в отдельную программу или COM-объект и пометить программу манифестом или запустить COM-объект с помощью Псевдоним COM.
Ага, Майк, это то, что я заметил после того, как пометил это как «ответ». То есть - я на самом деле было написал полный путь "System32" в моем тесте, так что он все равно должен был выбрать 64-битную версию, но не сделал этого. Я предположил, что это произошло по той причине, на которую вы указали. :)
Комментарий «все, что появляется первым в PATH», не совсем правильный. В PATH указано system32, 32 или 64 бит. При вызове ShellExecute из 32-битного процесса вы получаете перенаправление файловой системы на syswow64. Это не значит, что вы можете поменять местами порядок, в котором системный каталог появляется в вашей переменной PATH, и изменить поведение !!
Я не думаю, что этот ответ сработает по причинам, которые предлагает Майкл. @Jonas, вы можете "отменить" его, снова щелкнув галочку
попробуйте это (из 32-битного процесса):
> %WINDIR%\sysnative\reg.exe query ...
(обнаружил, что здесь).
Если это сработает, это звучит как хороший трюк, чтобы иметь его в сумке.
@DavidHeffernan: Итак, вы поймали ошибку и попытаетесь снова использовать System32.
@DavidHeffernan Есть исправление, которое делает sysnative работу на XP64: 32-разрядное приложение не может получить доступ к папке system32 на компьютере под управлением 64-разрядной версии Windows Server 2003 или Windows XP
Одна вещь, которую я сделал для себя, - это отключение перенаправления PInvoke:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365744(v=vs.85).aspx
Вы всегда можете снова включить его.
Не забывайте, что из-за перенаправления файловой системы (или того, что MS называет), 32-разрядный процесс, который пытается открыть / exec "c: \ Windows \ System32 \ foo.exe", будет открывать этот файл / выполнять перенаправление автоматически в «C: \ windows \ SysWow64 \ foo.exe», если не приняты специальные меры для отключения перенаправления.