Yeesh. Driest title ever, but I really couldn’t find a better one. Anyway – there comes a time in a programmers life when he has to set an environment variable globally, so that other processes can use it. How to do that under Win32 is, despite an entry in Microsoft’s KB not exactly well known. Probably due to the fact that they managed to make their title sound even more arcane than I did.

In a nutshell, you set the registry key corresponding with your environment variable and send a WM_SETTINGCHANGE message system-wide. And since it’s a system-wide send, you need to send with SendMessageTimeout – otherwise a single hung process will bring your program to a halt, too.

There’s only a small extra bit of information I can add: If you make this change from a program that keeps running, SendNotifyMessage() is a better choice – there’s no timeout, and Windows will keep trying to deliver your message. Without actually hanging your process. Obviously, this doesn’t work when you terminate your program, since the data you’re sending is now non-existant. (That’s what you get for sending around pointers…)

And, since I need this from time to time and love a code sample, here’s the actual code. [Formatting deliberate to squeeze on page]

    char* pRegistryKey  = 
        "SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
    char* pVariableName = "SOMEVAR";
    char* pValue        = "Another String bites the dust!";
    HKEY keyHandle;

if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
                  pRegistryKey, 0, 
                  KEY_SET_VALUE, &keyHandle ) 
    != ERROR_SUCCESS ) 
 { return 1; }

if( RegSetValueEx( keyHandle, 
                   pVariableName, 0, 
                   REG_SZ, (BYTE*)pValue, 
                   (DWORD)strlen( pValue ) + 1) 
     != ERROR_SUCCESS )
{ return 2; }

RegCloseKey( keyHandle );

DWORD returnValue;
SendMessageTimeout( HWND_BROADCAST, 
                    WM_SETTINGCHANGE, 
                    0, (LPARAM)"Environment", 
                    SMTO_ABORTIFHUNG, 5000, 
                    &returnValue);

Leave a reply