Como pode aplicação de 32 bits encontrar a localização de 64-bit do diretório Arquivos de programas no Windows Vista 64 bits?
-
21-09-2019 - |
Pergunta
Eu estou lutando com um problema de como determinar a localização do Programa de 64 bits diretório de Arquivos de 64 bits do Windows Vista a partir de uma aplicação de 32 bits.
Chamadas para SHGetKnownFolderPath(FOLDERID_ProgramFilesX64)
não retornam nada.O MSDN artigo Knownfolderid. aspx também afirma que esta chamada particular com FOLDERID_ProgramFilesX64
não é suportado para uma aplicação de 32 bits.
Eu gostaria de evitar, o máximo possível codificar o caminho "C:\Program Arquivos".Fazer algo como GetWindowsDirectory()
, extrair a unidade do valor de retorno e adicionando "\Arquivos de programas" para ele não é atraente tanto.
Como pode uma aplicação de 32 bits corretamente a obter a localização da pasta a partir de 64 bits do Windows Vista?
Fundo
Nosso aplicativo tem um componente de serviço, que é suposto para iniciar outros processos com base nas solicitações do usuário da sessão de componente específico.Os aplicativos iniciados podem ser de 32 bits ou de 64 bits.Fazer isso é através de CreateProcessAsUser()
passando um token de iniciar usuário-processo de sessão.Para chamar a CreateProcessAsUser
, criamos um ambiente de bloco através do CreateEnvironmentBlock()
API.O problema é que CreateEnvironmentBlock()
, usando o token do usuário-sessão de aplicação, cria um bloco com ProgramW6432="C:\Program Files (x86)", que é um problema para aplicativos de 64 bits.Nós precisamos substituí-la com o valor correto.
Solução
Como você mencionou, o uso do ShgetknownFolderPath de um aplicativo de 32 bits não funcionará em um sistema operacional de 64 bits. Isso ocorre porque a emulação do WoW64 está em vigor.
Você pode, no entanto, usar RegopenKeyEx Passando na bandeira KEY_WOW64_64KEY
e, em seguida, leia o diretório de arquivos do programa do Registry.
A localização no registro:
Hkey_local_machine software microsoft windows currentVersion
Você está interessado no valor da string:
Programfilesdir
Outras dicas
Se você ler essa página com cuidado, verá que o FolderID_Programfilesx64 é suportado para aplicativos de 32 bits em um sistema operacional de 64 bits. Não é suportado em um sistema operacional de 32 bits, o que faz todo o sentido.
FOLDERID_ProgramFilesX64 é suportado...
MSDN diz que é suportada, mas a Microsoft de "WOW64" melhores práticas documento diz que ele não é.Ver http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx
Citar:
• Algumas variáveis funcionam apenas se o processo for de 64 bits.Por exemplo, FOLDERID_ProgramFilesX64 não funciona para a versão de 32 bits chamadores.Nas versões do Windows anteriores ao Windows 7, %ProgramW6432% não trabalho no contexto dos processos de 32 bits.Um aplicativo deve determinar se ele está sendo executado em um processo de 64 bits antes de utilizar estas variáveis.
No Windows 7 x64 executando uma versão de 32 bits do aplicativo no depurador do Visual Studio, eu também obter um código de retorno de 0 x 80070002 (e um ponteiro NULO).Com o mesmo código compilado como de 64 bits retorna o valor S_OK e o caminho está corretamente preenchida.
Eu usei o hack de registro, conforme listado acima, já que eu não posso encontrar qualquer outra solução.
Você também pode consultar a variável do ambiente ProgramW6432
. Obviamente, ele existe apenas no Windows de 64 bits, mas deve retornar o diretório real de arquivos de programas de 64 bits e parece estar definido para programas de 64 e 32 bits. Pelo menos funcionou para mim (C#, GetEnvironmentVariable
)...