3

I am currently writing an unmanaged C++ program which works with a system environment variable. I am getting the value with GetEnvironmentVariable(...). Now I have an C# program which may change this variable at any time, e.g. like this:

Environment.SetEnvironmentVariable("CalledPath", System.Windows.Forms.Application.ExecutablePath, EnvironmentVariableTarget.Machine);

The problem is that the C++ program does not update this variable (or its environment block in general) automatically so that I am still working with the old value unless I restart the program which is not really good. Is there a way to update the environment block or preferably another way to read system environment variables?

Thanks in advance, Russo

Russo
  • 405
  • 1
  • 4
  • 10

6 Answers6

4

To make a long story short, environment variables won't work dependably as a form of inter-process communication -- you really need to switch to something else.

To work, both programs would need access to some common block of environment variables -- but in reality, each process gets its own, independent copy of a set of environment variables. Worse, most typical (C and C++) standard libraries don't let you even work with that directly -- instead, they make another copy of the environment variables for you to work with. When/if you call getenv() or _putenv(), only the program's internal copy of the environment variable block is involved. This means even if you could change a process' environment variables, the program running in that process still wouldn't get the new data.

So, you really need to re-think what you're doing. There are lots of possibilities for sending data from one program to another, including a Windows message (E.g. WM_COPYDATA), an anonymous or named pipe, a mailslot, a shared memory region, a socket, etc. The list is long, but still doesn't include environment variables.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
4

Thank you guys but I finally figured it out myself. Since the values I receive with GetEnvironmentVariable are not the current ones I read the values directly from the registry. The machine environment variables are stored in

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

I read them via the RegOpenKeyEx(...) and RegQueryValueEx(...) functions which works perfectly well.

Russo
  • 405
  • 1
  • 4
  • 10
1

You can't. Each process gets a copy of the environment variables of its parent. As it only gets a copy, it can't change the parent's environment, or that of any other running process.

1

You are persisting the environment variable changes for as long as is possible, in the context of the call you show. See this MSDN explanation of the EnvironmentVariableTarget enumeration.

With the EnvironmentVariableTarget.Machine setting you use now, the variable change will persist for as long as your program's process runs, so all other processes will be able to read this variable for the duration of your program's execution:

The environment variable is stored or retrieved from the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment key in the Windows operating system registry.

When a user creates the environment variable in a set operation, the operating system stores the environment variable in the system registry, but not in the current process. If any user on the local machine starts a new process, the operating system copies the environment variable from the registry to that process.

When the process terminates, the operating system destroys the environment variable in that process. However, the environment variable in the registry persists until a user removes it programmatically or by means of an operating system tool. [Emphasis mine.]

Daniel F. Thornton
  • 3,687
  • 2
  • 28
  • 41
-2

Look at putenv() - a C-runtime function (or the MS preferred _putenv() and _putenv_s() - for your C++ equivalent for updating.

getenv() and similar reads in an environment string.

K

Kevin Shea
  • 920
  • 7
  • 12
-2

I believe it's _putenv() on Windows.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171