设置用户环境变量非常慢

设置用户环境变量非常慢

我正在使用适用于 Windows 的 GitHub 应用程序。最近我注意到从 GitHub 应用程序内部启动 PowerShell 控制台需要很长时间。经过一番挖掘,我发现缓慢的命令正在设置环境变量。更具体地说,GitUtils.ps1(GitHub 使用的 PoshGit 的一部分)中的这些行:

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

设置进程范围的变量是即时的,但设置用户变量需要很长时间。使用以下脚本:

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

我可以看到此操作需要 80 多秒。使用默认高级设置窗口设置用户环境变量很快。使用快速环境编辑器设置变量通常很快,但有时需要 5-10 秒,但绝不会这么长。

有谁能提出什么原因导致这种情况?

答案1

根据环境类别来源(可以找到这里,第 864 行),在设置用户/机器范围环境变量后,它会调用本机 SendMessageTimeout 函数来通知任何进程有关环境的变化。以下是摘录:

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

因此,每个收件人都有 1000 毫秒(1 秒)的超时时间来处理消息。例如,如果其中 5 个收件人无法处理该消息,则可能会有最多 5 秒的延迟。有关 SendMessageTimeout 的更多信息,请参阅微软

希望有所帮助。

相关内容