Definir variáveis de ambiente do usuário é muito lento

3

Estou usando o aplicativo GitHub for Windows. Ultimamente, percebi que iniciar um console do PowerShell a partir do aplicativo GitHub leva muito tempo. Depois de algumas escavações, descobri que o comando lento está definindo uma variável de ambiente. Mais especificamente, estas linhas no GitUtils.ps1 (parte do PoshGit que o GitHub usa):

function setenv($key, $value) {
    [void][Environment]::SetEnvironmentVariable($key, $value, [EnvironmentVariableTarget]::Process)
    [void][Environment]::SetEnvironmentVariable($key, $value, [EnvironmentVariableTarget]::User)
}

Definir a variável de todo o processo é instantânea, mas a variável de usuário leva muito tempo. Usando o seguinte script:

$sw = [Diagnostics.Stopwatch]::StartNew()
[Environment]::SetEnvironmentVariable("Horses", "are neat", [EnvironmentVariableTarget]::User)
$sw.Stop()
$sw.Elapsed

Eu posso ver que esta operação leva mais de 80 segundos. Definir um usuário Env env usando a janela de configurações avançadas padrão é rápido. Usando o Rapid Environment Editor, a configuração de um var geralmente é rápida, mas às vezes leva de 5 a 10 segundos, mas nunca é tão longa quanto isso.

Alguém tem alguma sugestão para o que pode estar causando isso?

    
por Bjørn Madsen 14.03.2013 / 11:06

1 resposta

7

De acordo com fontes da classe Environment (pode ser encontrado aqui , linha 864), depois de definir variável de ambiente de escopo user / machine, ele chama a função SendMessageTimeout nativa para notificar qualquer processo sobre alterações no meio ambiente. Aqui está um trecho:

IntPtr r = Win32Native.SendMessageTimeout(
    new IntPtr(Win32Native.HWND_BROADCAST), 
    Win32Native.WM_SETTINGCHANGE, 
    IntPtr.Zero, 
    "Environment", 
    0, 
    1000, 
    IntPtr.Zero);

Portanto, o tempo limite de 1000 milissegundos (1 segundo) é dado a qualquer destinatário para processar a mensagem. Por exemplo. Se 5 deles não conseguir processá-lo, você poderá ter um atraso de até 5 segundos. Mais sobre SendMessageTimeout pode ser encontrado em MSDN .

Espero que ajude.

    
por 14.03.2013 / 21:08