Environment Variables: Example 2
Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process. If you want the child process to inherit most of the parent's environment with only a few changes, retrieve the current values using GetEnvironmentVariable(), save these values, create an updated block for the child process to inherit, create the child process, and then restore the saved values using SetEnvironmentVariable(), as shown in the following example. This example uses the code in example 3 as the child process, EnvironVar3.exe.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 4096
#define VARNAME LMyVariable
int wmain(int argc, WCHAR **argv)
{
DWORD dwRet, dwErr;
LPTSTR pszOldVal;
// The path of the child program
WCHAR szAppName[]=LC:\\amad\\EnvironVar3\\Debug\\EnvironVar3.exe;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL fExist, fSuccess;
DWORD Ret;
// Retrieves the current value of the variable if it exists.
// Sets the variable to a new value, creates a child process,
// then uses SetEnvironmentVariable to restore the original
// value or delete it if it did not exist previously
pszOldVal = (LPTSTR)malloc(BUFSIZE*sizeof(WCHAR));
if(pszOldVal == NULL)
{
wprintf(LOut of memory!\n);
return FALSE;
}
else
wprintf(Lmalloc() should be fine!\n);
dwRet = GetEnvironmentVariable(VARNAME, pszOldVal, BUFSIZE);
if(dwRet == 0)
{
dwErr = GetLastError();
if(dwErr == ERROR_ENVVAR_NOT_FOUND)
{
wprintf(LThe given environment variable does not exist!\n);
fExist=FALSE;
}
}
else if(BUFSIZE < dwRet)
{
pszOldVal = (LPTSTR)realloc(pszOldVal, dwRet*sizeof(WCHAR));
if(pszOldVal == NULL)
{
wprintf(LOut of memory!\n);
return FALSE;
}
dwRet = GetEnvironmentVariable(VARNAME, pszOldVal, dwRet);
if(!dwRet)
{
wprintf(LGetEnvironmentVariable() failed! Error %d\n, GetLastError());
return FALSE;
}
else
{
wprintf(LGetEnvironmentVariable() - The environment variable exists!\n);
fExist=TRUE;
}
}
else
{
wprintf(LGetEnvironmentVariable() is OK!\n);
fExist = TRUE;
}
// Set a value for the child process to inherit
if (!SetEnvironmentVariable(VARNAME, LTest))
{
wprintf(LSetEnvironmentVariable() failed! Error %d\n, GetLastError());
return FALSE;
}
else
wprintf(LSetEnvironmentVariable() is OK! Environment variable was set\n);
// Create a child process
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
fSuccess = CreateProcess(szAppName, NULL, NULL, NULL, TRUE, 0,
NULL, // inherit parent's environment
NULL, &si, &pi);
if(!fSuccess)
{
wprintf(LCreateProcess() failed! Error %d\n, GetLastError());
}
else
wprintf(LCreateProcess() is OK!\n);
Ret = WaitForSingleObject(pi.hProcess, INFINITE);
wprintf(LThe WaitForSingleObject() return value is 0X%.8X\n, Ret);
// Restore the original environment variable
if(fExist)
{
if(!SetEnvironmentVariable(VARNAME, pszOldVal))
{
wprintf(LSetEnvironmentVariable() failed! Error %d\n, GetLastError());
return FALSE;
}
else
wprintf(LSetEnvironmentVariable() - Restoring the old environment variable!\n);
}
else
{
wprintf(LSetEnvironmentVariable() - Removing the new environment variable!\n);
SetEnvironmentVariable(VARNAME, NULL);
}
free(pszOldVal);
return fSuccess;
}
Build and run the project. The following screenshot are sample outputs.
The Windows’s set command can be used to manipulate the environment variables.