我正在使用适用于 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 的更多信息,请参阅微软。
希望有所帮助。