Platform SDK: DLLs, Processes, and Threads

Changing Environment Variables

Each process has an environment block associated with it. The environment block consists of a null-terminated block of null-terminated strings (meaning there are two null bytes at the end of the block), where each string is in the form:

name=value 

All strings in the environment block must be sorted alphabetically by name. The sort is case-insensitive, Unicode order, without regard to locale. Because the equal sign is a separator, it must not be used in the name of an environment variable.

By default, a child process inherits a copy of the environment block of the parent process. The following example demonstrates how to create a new environment block to pass to a child process.

LPTSTR lpszCurrentVariable; 
BOOL fSuccess; 
 
// Copy environment strings into an environment block. 
 
lpszCurrentVariable = tchNewEnv; 
if (lstrcpy(lpszCurrentVariable, "API=Win32") == NULL) 
   ErrorExit("lstrcpy failed"); 
 
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1; 
if (lstrcpy(lpszCurrentVariable, "OperatingSystem=Windows") == NULL) 
   ErrorExit("lstrcpy failed"); 
 
// Terminate the block with a NULL byte. 
 
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1; 
*lpszCurrentVariable = '\0'; 
 
// Create the child process, specifying a new environment block. 
 
fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0, 
   (LPVOID) tchNewEnv,        // new environment block 
   NULL, &siStartInfo, &piProcInfo); 
 
if (! fSuccess) 
    ErrorExit("CreateProcess failed"); 

If you want the child process to inherit most of the parent's environment with only a few changes, save the current values, make changes for the child process to inherit, create the child process, and then restore the saved values, as shown following.

LPTSTR lpszOldValue; 
TCHAR tchBuf[BUFSIZE]; 
BOOL fSuccess; 
 
// lpszOldValue gets current value of "varname", or NULL if "varname" 
// environment variable does not exist. Set "varname" to new value, 
// create child process, then use SetEnvironmentVariable to restore 
// original value of "varname". If lpszOldValue is NULL, the "varname" 
// variable will be deleted. 
 
lpszOldValue = ((GetEnvironmentVariable("varname", 
    tchBuf, BUFSIZE) > 0) ? tchBuf : NULL); 
 
// Set a value for the child process to inherit. 
 
if (! SetEnvironmentVariable("varname", "newvalue")) 
   ErrorExit("SetEnvironmentVariable failed"); 
 
// Create a child process. 
 
fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0, 
   NULL,     // inherit parent's environment 
   NULL, &siStartInfo, &piProcInfo); 
if (! fSuccess) 
   ErrorExit("CreateProcess failed"); 
 
// Restore the parent's environment. 
 
if (! SetEnvironmentVariable("varname", lpszOldValue)) 
   ErrorExit("SetEnvironmentVariable failed"); 

The following example, taken from a console process, prints the contents of the process's environment block.

LPTSTR lpszVariable; 
LPVOID lpvEnv; 
 
// Get a pointer to the environment block. 
 
lpvEnv = GetEnvironmentStrings(); 
 
// Variable strings are separated by NULL byte, and the block is 
// terminated by a NULL byte. 
 
for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) 
{ 
   while (*lpszVariable) 
      putchar(*lpszVariable++); 
   putchar('\n'); 
}