9

Is there any way I can add environment variable in Windows via C++?

They have to be added in "My computer->properties->advanced->environment variables"

Thank you

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
VextoR
  • 5,087
  • 22
  • 74
  • 109
  • 2
    possible duplicate of [Programmatically adding a directory to Windows PATH environment variable](http://stackoverflow.com/questions/1919125/programmatically-adding-a-directory-to-windows-path-environment-variable) – Joe Mar 09 '11 at 12:54
  • possible duplicate of [Set local environment variables in C++](http://stackoverflow.com/questions/899517/set-local-environment-variables-in-c) – Aamir Mar 09 '11 at 12:54
  • 1
    @Aamir: OP said "in Windows". Your link requires it only for the running process. Also see the reply from Felice Pollano which makes the same (IMO wrong) assumption. – 0xC0000022L Mar 09 '11 at 12:59

6 Answers6

11

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 ...

Julien Roncaglia
  • 17,397
  • 4
  • 57
  • 75
SteelBytes
  • 6,905
  • 1
  • 26
  • 28
3

Here's a simple implementation (Based on the MSDN instruction posted by SteelBytes):

bool SetPermanentEnvironmentVariable(LPCTSTR value, LPCTSTR data)
{
    HKEY hKey;
    LPCTSTR keyPath = TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Environment");
    LSTATUS lOpenStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyPath, 0, KEY_ALL_ACCESS, &hKey);
    if (lOpenStatus == ERROR_SUCCESS) 
    {
        LSTATUS lSetStatus = RegSetValueEx(hKey, value, 0, REG_SZ,(LPBYTE)data, strlen(data) + 1);
        RegCloseKey(hKey);

        if (lSetStatus == ERROR_SUCCESS)
        {
            SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_BLOCK, 100, NULL);
            return true;
        }
    }

    return false;
}
Nati
  • 63
  • 1
  • 8
3

The only way I know is via the registry.

Hint, the global variables are in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and those for each user in HKEY_USERS\*\Environment, where * denotes the SID of the user.

Good luck.

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
  • After independent research myself that led me here, I found this to be the easiest mechanism. Just remember that every process that existed *before* you updated the path environment variable may or may not respond as it should to the message you are supposed to send after updating it. Meaning, the change may only apply to new processes. – dyasta Jul 26 '17 at 22:02
2

Have you tried Set local environment variables in C++?

Community
  • 1
  • 1
ADringer
  • 2,614
  • 36
  • 63
  • It's worth noting environment variables created with putenv (or _putenv in Windows) do not persist after the program that created them exits (as the word local indicates). +1 because this solves the problem if you only need the environment variable to be around for the program lifetime – Ben Aug 09 '22 at 09:41
-1

The environment variables in Windows are stored in Windows Registry. You can use "System.Environment.SetEnvironmentVariable" .NET function for the purpose, please see the documentation of the function at link below.

http://msdn.microsoft.com/en-us/library/96xafkes.aspx

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
Tayyab
  • 9,951
  • 1
  • 16
  • 19
  • 1
    He wants to set the variables globally; this function only applies to the current process. – SLaks Mar 10 '11 at 02:21
  • I think you haven't read the documentation of the function. The function can set the variable for "Process" or "User" or "Machine". You can do it at machine level by passing targer = EnvironmentVariableTarget.Machine – Tayyab Mar 11 '11 at 09:18
  • That's a C# function; he's asking about C++. – SLaks Mar 11 '11 at 13:39
  • OK if you don't want to agree, What can I say. I won't comment any further. Just one last thing for your information. This method can be called fom C++, C#, VB and F# (see given link for sample code for all languages). I agree that the function is part of Framework and is not part of Win32 but the asked question doesn't require that. The question just says "C++ on Windows". I suppose you didn't read the question carefully. Anyways have fun !! :) – Tayyab Mar 11 '11 at 19:23
  • "C++ on Windows" cannot call .Net methods. (few people use C++/CLI) – SLaks Mar 11 '11 at 19:44
  • @SLaks Just stumbled upon this. There is actually a C++ function with the same name, that does the same: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx – Simon Kraemer Dec 21 '16 at 14:17
  • That is a Win32 API and has the same local effect I am describing below. Slaks is right. When a new Windows process is created it gets an entire copy of the environment in it's Process Environment Block (this is why a message should be sent after updating). This method only affects that local process, or *children* of that process, if applicable. It has no permanence. – dyasta Jul 26 '17 at 21:56
-1
#include <iostream>
#include <windows.h>
#include <cstring>
#include "tchar.h"


void SetUserVariablePath(){
    HKEY hkey;
    long regOpenResult;
    const char key_name[] = "Environment";
    const char path[]="D:/custom_command";                                               //new_value path need to update 
    regOpenResult = RegOpenKeyEx(HKEY_CURRENT_USER,key_name, 0, KEY_ALL_ACCESS, &hkey);
    LPCSTR stuff = "VVS_LOGGING_PATH";                                                   //Variable Name 
    RegSetValueEx(hkey,stuff,0,REG_SZ,(BYTE*) path, strlen(path));
    RegCloseKey(hkey);
}



void GetUserVariablePath(){
    static const char path[] = "VVS_LOGGING_PATH" ;                                      //Variable Name 
    static BYTE buffer1[1000000] ;
    DWORD buffsz1 = sizeof(buffer1) ;
    {
        //HKEY_CURRENT_USER\Environment
        const char key_name[] = "Environment";
        HKEY key ;

        if( RegOpenKeyExA( HKEY_CURRENT_USER, key_name, 0, KEY_QUERY_VALUE, std::addressof(key) ) == 0 &&
            RegQueryValueExA( key, path, nullptr, nullptr, buffer1, std::addressof(buffsz1) ) == 0 )
        {
            std::cout << "The updated value of the user variable is :  " << reinterpret_cast<const char*>(buffer1) << '\n' ;
        }
    }
}

int main()
{   
    SetUserVariablePath();
    GetUserVariablePath();
    return 0;
}
b_tech
  • 19
  • 1
  • Welcome to Stack Overflow. It would be nice if you were to explain why your answer is better than those already provided. – Angel F Syrus May 31 '19 at 04:47