views:

591

answers:

4

I'm using the Win32 function GetEnvironmentVariable to retrieve the value of a variable that I just created. I'm running Windows XP and VC++ 2005. If I run the program from within Visual Studio, it can't find the new variable. If I run it from a command-prompt, it does. I restarted VC++ but same result. I even restarted all instances of Visual Studio but still the same problem. It might get resolved if I reboot the PC but I'm curious why this is so. Here's the code that I'm using:

#define BUFSIZE 4096
#define VARNAME TEXT("MY_ENV_NAME")

int _tmain(int argc, _TCHAR* argv[])
{
 TCHAR chNewEnv[BUFSIZE];

 DWORD dwEnv = ::GetEnvironmentVariable(VARNAME, chNewEnv, BUFSIZE);
 if (dwEnv == 0)
 {
  DWORD dwErr = GetLastError();
  if(dwErr == ERROR_ENVVAR_NOT_FOUND)
  {
   printf("Environment variable does not exist.\n");
   return -1;
  }
 }
 else
 {
  printf(chNewEnv);
 }

 return 0;
}

If I replace MY_ENV_NAME with something that must exist, such as TEMP, it works as expected. Any ideas? Thanks.

+3  A: 

Make sure you restart the application before you can read the environment variable. The same happens if you have a console window open and change the environment variables on My Computer, these are not noted in any existing console windows. You need to restart them to get a copy of the new environment variables.

Anders K.
Anders, I did restart my consoles as well as Visual studio
Amit G
And the program you started with VisStudio from. An application inherits its environment from its 'parent' at start up and does not change. After start up changes to the environment in context X are not propagated to context Y.
Martin York
+3  A: 

Expanding on what Anders and Martin said, environment variables are one thing that is inherited when starting an application. The new program basically gets a copy of the environment at the time it was started. When debugging, your exe is generally started by Visual Studio, so your application will have the same environment as Visual Studio. Visual Studio, is generally started by explorer. If you change the environment variables by going to System Properties->Advanced->Envronment Variables then you will have to restart Visual Studio to see the changes.

If you need to see the envronment variables that Visual Studio is seeing you can (at least for VS2005/2008) go to Tools...->options...->Projects and Solutions->VC++ Project Settings and set Show Environment in Log to 'Yes.' This will print out all the environment variables to the build log (ctrl+click on the link in your build output). You have to build to get this info, but this is the best way I know of seeing the VS environment.

If you really need to change environment variables then run and are having a hard time debugging, you can build your debug exe and have a call to DebugBreak() somewhere near where you want to start debugging from. Then you can set your environment how you want, start the exe from explorer or the command prompt. Then (assuming you have JIT debugging enabled) you will get a popup when your code gets to the DebugBreak() call and you can attach to it with VS and debug normally from there.

Dolphin
Great tip regarding outputing the environment in the Log, very useful!
Amit G
+1  A: 

It all depends on how you set the environment variable:

  • If you ran set MY_ENV_NAME=val in a command prompt, then you have set MY_ENV_NAME for that instance of cmd.exe and any child processes it executes in the future. The environment of existing child processes is not modified.

    In this case, exiting the Visual Studio IDE and starting it from the command line (not Explorer) should cause it and its child processes to see the new environment variable.

  • If you used the System or Users control panel or the setx command to set MY_ENV_NAME, then you have set MY_ENV_NAME persistently, and it will be set for all processes after you reboot your computer. In addition, you may find that some processes, such as Explorer, pick up the environment variable change immediately.

    This works by storing the new environment variable in the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment or HKEY_CURRENT_USER\Environment, depending on whether you chose to set a system environment variable or a per-user environment variable. Existing processes are notified that there was an environment variable change by broadcasting the WM_SETTINGCHANGE message with lParam=="Environment". This message causes them to re-read the persistent environment variables from the registry if they know how. KB104011 has more details.

    As a result, if you use the System or Users control panel to set a new environment variable, exiting the Visual Studio IDE and starting it again from Explorer (not a command prompt) should cause it and its child processes to see the new environment variable.

bk1e
A: 

Thanks for all the responses. As I mentioned in my question, I tried restarting everything, short of rebooting the PC. It turns out that because my environment variable was a SYSTEM variable, VS doesn't recognize it without rebooting the PC. When I moved the env variable from SYSTEM to USER and restarted VS, it worked fine.

Amit G