Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm using the GitHub for Windows application. Lately I've noticed that starting a PowerShell console from within the GitHub application takes ages. After some digging I've found that the slow command is setting an environment variable. More specifically these lines in GitUtils.ps1 (part of PoshGit that GitHub uses):

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

Setting the Process-wide variable is instant, but the User variable takes a long time. Using the following script:

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

I can see that this operation takes over 80 seconds. Setting a User env var using the default advanced settings window is fast. Using Rapid Environment Editor, setting a var is usually fast, but sometimes takes 5-10 seconds, but never anything as long as this.

Anyone have any suggestions to what may be causing this?

share|improve this question
    
Please note that calling Environment.SetEnvironmentVariable with the EnvironmentVariableTarget.User parameter will result in direct registry access (in contrast to a simple WINAPI call). –  Oliver Salzburg Mar 14 '13 at 10:56
    
@OliverSalzburg Is there another way to set a user env var from PowerShell? –  Bjørn Madsen Mar 19 '13 at 8:49
    
Sorry, I am not aware of any. –  Oliver Salzburg Mar 19 '13 at 10:52

1 Answer 1

up vote 4 down vote accepted

According to Environment class sources (can be found here, line 864), after setting user/machine scope environment variable, it calls native SendMessageTimeout function to notify any process about changes in environment. Here is excerpt:

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

So 1000 milliseconds (1 second) timeout is given to any recipient to process the message. E.g. if 5 of them fail to process it, you could have up to 5 seconds delay. More about SendMessageTimeout can be found in MSDN.

Hope that helps.

share|improve this answer
    
Interesting. Would this mean I have 80+ subscribers to that message that all let it timeout? –  Bjørn Madsen Mar 19 '13 at 8:50
1  
Apparently it's Google Chrome that's the culprit here. If I close Chrome, the operation completes in a couple of seconds. Wonder why Chrome lets those messages time out. –  Bjørn Madsen Mar 19 '13 at 8:55
    
I guess this might require digging into Chrome code... Another idea is that Chrome application usually runs in dozens of processes, each tab and extension is in a separate one. Perhaps, the more tabs open/extensions you have, the more time it will take to process the system message. –  Dmitry Mar 19 '13 at 12:51
    
I used an external program for my VBA app (since you can't do threads in VBA), this does work for me codeguru.com/cpp/w-p/win32/tutorials/article.php/c10849/… –  RaB Oct 27 '13 at 9:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.