Set Local Environment Variables in C++

Set local environment variables in C++


NAME

putenv - change or add an environment variable

SYNOPSIS

#include <stdlib.h>

int putenv(char *string);

DESCRIPTION
The putenv() function adds or changes the value of environment
variables. The argument string is of the form name=value. If name does
not already exist in the environment, then string is added to the
environment. If name does exist, then the value of name in the
environment is changed to value. The string pointed to by string becomes
part of the environment, so altering the string changes the environment.

On Win32 it's called _putenv I believe.

See SetEnvironmentVariable also if you're a fan of long and ugly function names.

Set environment variables in C

I'm going to make a wild guess here, but the normal reason that these functions appear to not work is not because they don't work, but because the user doesn't really understand how environment variables work. For example, if I have this program:

int main(int argc, char **argv)
{
putenv("SomeVariable=SomeValue");
return 0;
}

And then I run it from the shell, it won't modify the shell's environment - there's no way for a child process to do that. That's why the shell commands that modify the environment are builtins, and why you need to source a script that contains variable settings you want to add to your shell, rather than simply running it.

Setting environment variable in C

Please show me the way you get the environment variable after you set it up.
I've got the following C code working for me as expected:

#include <stdio.h>
#include <stdlib.h>

int main()
{
char path[100]="PATH=";
char *input = "/newfolder/hello/";
putenv(strcat(path, input));

char* pPath;
pPath = getenv("PATH");

printf("%s", pPath);

return 0;
}

Output is: /newfolder/hello/

I am trying to print it back out using echo $PATH and it still shows the former path, as in it is not changed.

Is you using in your program something like:

system("echo $PATH");

Then you wouldn't get that value you have set, since this command will be executed and evaluated from your shell process which is still having initial environment variable set values.

Proper setting a local environment variable in C++

putenv normally allows the string to be changed after the call to putenv and that actually automatically changes the environment. That is the reason why the prototype declares a char * instead of a const char *, but the system will not change the passed string.

So this is one of the rare correct use cases for a const cast:

putenv(const_cast<char *>("TZ=UTC"));

Alternatively, you could use setenv that takes const char * parameters:

setenv("TZ", "UTC", 1);

How to add environment variable in C++?

from MSDN :

To programmatically add or modify
system environment variables, add them
to the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then
broadcast a WM_SETTINGCHANGE message
with lParam set to the string
"Environment". This allows
applications, such as the shell, to
pick up your updates ...

How to set system environment variable in C#?

The documentation tells you how to do this.

Calling SetEnvironmentVariable has no effect on the system environment variables. To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". This allows applications, such as the shell, to pick up your updates.

So, you need to write to the registry setting that you are already attempting to write to. And then broadcast a WM_SETTINGCHANGE message as detailed above. You will need to be running with elevated rights in order for this to succeed.

Some example code:

using Microsoft.Win32;
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
class Program
{
const int HWND_BROADCAST = 0xffff;
const uint WM_SETTINGCHANGE = 0x001a;

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg,
UIntPtr wParam, string lParam);

static void Main(string[] args)
{
using (var envKey = Registry.LocalMachine.OpenSubKey(
@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
true))
{
Contract.Assert(envKey != null, @"registry key is missing!");
envKey.SetValue("TEST1", "TestValue");
SendNotifyMessage((IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE,
(UIntPtr)0, "Environment");
}
}
}
}

However, whilst this code does work, the .net framework provides functionality to perform the same task much more simply.

Environment.SetEnvironmentVariable("TEST1", "TestValue", 
EnvironmentVariableTarget.Machine);

The documentation for the three argument Environment.SetEnvironmentVariable overload says:

If target is EnvironmentVariableTarget.Machine, the environment variable is stored in the HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment key of the local computer's registry. It is also copied to all instances of File Explorer. The environment variable is then inherited by any new processes that are launched from File Explorer.

If target is User or Machine, other applications are notified of the set operation by a Windows WM_SETTINGCHANGE message.

How do I get and set Environment variables in C#?

Use the System.Environment class.

The methods

var value = System.Environment.GetEnvironmentVariable(variable [, Target])

and

System.Environment.SetEnvironmentVariable(variable, value [, Target])

will do the job for you.

The optional parameter Target is an enum of type EnvironmentVariableTarget and it can be one of: Machine, Process, or User. If you omit it, the default target is the current process.



Related Topics



Leave a reply



Submit