Esses dias me deparei com um de meus sistemas gerando alguns erros de funcionamento no windows vista.
Na verdade todos os problemas ocorriam pelo mesmo motivo, este sistema em específico armazena suas configurações no registro do windows na chave HKEY_LOCAL_MACHINE (pois todos os usuários devem poder acessar as mesmas configurações), o Vista por padrão deixou de permitir que nossas aplicações escrevam dados na chave HKEY_LOCAL_MACHINE sem que a aplicação seja executada como administrador, consequentemente caso abrirmos uma chave para consulta com os direitos de acesso total a aplicação não conseguirá nem mesmo ler o conteúdo da chave. Isso tudo acontece graças ao Controle de Contas de Usuários (UAC) do Vista. Na minha opinião é um recurso muito bom porém ainda poderia ser melhor, mas isso não vem ao caso agora. Vamos analizar o código anterior de nossa aplicação:
class function TFuncoes.LeParametro(nomeParametro: string): string;
const
csLocal: String = 'Software\Programa\';
var
rConfiguracoes: TRegistry;
begin
rConfiguracoes := TRegistry.Create;
try
rConfiguracoes.RootKey := HKEY_LOCAL_MACHINE;
if rConfiguracoes.KeyExists(csLocal) then
begin
if rConfiguracoes.OpenKey(csLocal, True) then
begin
if rConfiguracoes.ValueExists(nomeParametro) then
Result := rConfiguracoes.ReadString(nomeParametro) else
Result := EmptyStr;
end;
end;
finally
FreeAndNil(rConfiguracoes);
end;
end;
O código acima no Windows Vista retorna sempre um valor vazio ('') para que o mesmo funcione temos que tomar as seguintes precauções:
class function TFuncoes.LeParametro(nomeParametro: string): string;
const
csLocal: String = 'Software\Programa\';
var
rConfiguracoes: TRegistry;
begin
rConfiguracoes := TRegistry.Create;
try
rConfiguracoes.RootKey := HKEY_LOCAL_MACHINE;
//Após mudar a chave inicial setar o modo de acesso como leitura
rConfiguracoes.Access := KEY_READ;
if rConfiguracoes.KeyExists(csLocal) then
begin
//Garantir que todos os chamados ao metodo OpenKey sejam feitos como somente leitura (neste caso passando o parâmetro CanCreate como False.
if rConfiguracoes.OpenKey(csLocal, False) then
begin
if rConfiguracoes.ValueExists(nomeParametro) then
Result := rConfiguracoes.ReadString(nomeParametro) else
Result := EmptyStr;
end;
end;
finally
FreeAndNil(rConfiguracoes);
end;
end;
Desta forma garantimos a compatibilidade com o Windows Vista, porém lembre-se que caso seu sistema faça alterações nesta chave ele não conseguirá mudar os dados do registro se a aplicação não for executada como administrador. Eu recomendo mudar a forma que sua aplicação armazena as configurações.
Grande abraço a todos, espero que esta pequena dica seja útil a muitos de vocês que estão migrando para o vista.
Diego M. Garcia.