Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Environment Variables

Environment Variables

Scheduled Pinned Locked Moved C / C++ / MFC
c++questionworkspace
8 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jpyp
    wrote on last edited by
    #1

    I created an environment variable using the Windows System Properties page. In my program I called getenv("varname") to retrieve the value of my environment variable. After changing the value of my variable, I can see the change when running my program from the desktop but I get the old value when running the program from within MS Vis C++ unless I restart Vis C++. Obviously Vis C++ reads the environment settings and uses them from that point on. Is there any way to "refresh" the environment from within Vic C++ so that the next time I run my program, it picks up the new value? Thanks!

    jpyp

    M 1 Reply Last reply
    0
    • J jpyp

      I created an environment variable using the Windows System Properties page. In my program I called getenv("varname") to retrieve the value of my environment variable. After changing the value of my variable, I can see the change when running my program from the desktop but I get the old value when running the program from within MS Vis C++ unless I restart Vis C++. Obviously Vis C++ reads the environment settings and uses them from that point on. Is there any way to "refresh" the environment from within Vic C++ so that the next time I run my program, it picks up the new value? Thanks!

      jpyp

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #2

      jpyp wrote:

      Is there any way to "refresh" the environment from within Vic C++ so that the next time I run my program, it picks up the new value?

      I don't know if there's a way to do that in Visual Studio. This[^] may at least explain why it happens. Mark

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      J 1 Reply Last reply
      0
      • M Mark Salsbery

        jpyp wrote:

        Is there any way to "refresh" the environment from within Vic C++ so that the next time I run my program, it picks up the new value?

        I don't know if there's a way to do that in Visual Studio. This[^] may at least explain why it happens. Mark

        Mark Salsbery Microsoft MVP - Visual C++ :java:

        J Offline
        J Offline
        jpyp
        wrote on last edited by
        #3

        Looks like the only way to get the new value is to read it from the registry. Using regedit I can see the new value under key HKEY_CURRENT_USER\\Environment\\SSSRights which has a value of "A". But there seems to be something wrong with my code becomes I always get a return value of 87 which apparently means ERROR_INVALID_PARAMETER when I call RegQueryValueEx(). hMyKey has a valid handle after call to RegOpenKeyEx(). Here is my code:

        HKEY hMyKey;
        long lResult;
        LPDWORD pKeyType = REG_SZ;
        LPDWORD pKeySize = 0;
        char* strKeyName = "SSSRights";
        char* strKeyVal = "\0";

        RegOpenKeyEx(HKEY_CURRENT_USER, "Environment", 0, KEY_QUERY_VALUE, &hMyKey);

        lResult = RegQueryValueEx(hMyKey, strKeyName, NULL, pKeyType, (LPBYTE)strKeyVal, pKeySize);

        RegCloseKey(hMyKey);

        jpyp

        M 1 Reply Last reply
        0
        • J jpyp

          Looks like the only way to get the new value is to read it from the registry. Using regedit I can see the new value under key HKEY_CURRENT_USER\\Environment\\SSSRights which has a value of "A". But there seems to be something wrong with my code becomes I always get a return value of 87 which apparently means ERROR_INVALID_PARAMETER when I call RegQueryValueEx(). hMyKey has a valid handle after call to RegOpenKeyEx(). Here is my code:

          HKEY hMyKey;
          long lResult;
          LPDWORD pKeyType = REG_SZ;
          LPDWORD pKeySize = 0;
          char* strKeyName = "SSSRights";
          char* strKeyVal = "\0";

          RegOpenKeyEx(HKEY_CURRENT_USER, "Environment", 0, KEY_QUERY_VALUE, &hMyKey);

          lResult = RegQueryValueEx(hMyKey, strKeyName, NULL, pKeyType, (LPBYTE)strKeyVal, pKeySize);

          RegCloseKey(hMyKey);

          jpyp

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          You couldn't possibly compile that :) Try

          HKEY hMyKey;

          if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, _T("Environment"), 0, KEY_QUERY_VALUE, &hMyKey))
          {
          DWORD KeyType;
          DWORD KeySize = 0;
          TCHAR strKeyName[] = _T("SSSRights");

          if (ERROR_SUCCESS == ::RegQueryValueEx(hMyKey, strKeyName, NULL, &KeyType, NULL, &KeySize))
          {
          // Note: Assumes we KNOW the data type is REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ!!

            TCHAR \*pKeyVal = new TCHAR\[KeySize / sizeof (TCHAR)\];
          
            ::RegQueryValueEx(hMyKey, strKeyName, NULL, &KeyType, (LPBYTE)pKeyVal, &KeySize);
          
            // ... do something with the retrieved value (in the pKeyVal array) ...
          
            delete\[\] pKeyVal;
          

          }

          ::RegCloseKey(hMyKey);
          }

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          modified on Thursday, October 16, 2008 3:51 PM

          J 1 Reply Last reply
          0
          • M Mark Salsbery

            You couldn't possibly compile that :) Try

            HKEY hMyKey;

            if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, _T("Environment"), 0, KEY_QUERY_VALUE, &hMyKey))
            {
            DWORD KeyType;
            DWORD KeySize = 0;
            TCHAR strKeyName[] = _T("SSSRights");

            if (ERROR_SUCCESS == ::RegQueryValueEx(hMyKey, strKeyName, NULL, &KeyType, NULL, &KeySize))
            {
            // Note: Assumes we KNOW the data type is REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ!!

              TCHAR \*pKeyVal = new TCHAR\[KeySize / sizeof (TCHAR)\];
            
              ::RegQueryValueEx(hMyKey, strKeyName, NULL, &KeyType, (LPBYTE)pKeyVal, &KeySize);
            
              // ... do something with the retrieved value (in the pKeyVal array) ...
            
              delete\[\] pKeyVal;
            

            }

            ::RegCloseKey(hMyKey);
            }

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            modified on Thursday, October 16, 2008 3:51 PM

            J Offline
            J Offline
            jpyp
            wrote on last edited by
            #5

            Yes it compiled without any errors/problems. I tried yours and it works but it brings up the following questions: Why do I need the first call to RegQueryValueEx? What does it do? Why does the first call fail when I provide a buffer instead of NULL? Thanks!

            jpyp

            M 1 Reply Last reply
            0
            • J jpyp

              Yes it compiled without any errors/problems. I tried yours and it works but it brings up the following questions: Why do I need the first call to RegQueryValueEx? What does it do? Why does the first call fail when I provide a buffer instead of NULL? Thanks!

              jpyp

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #6

              What compiler are you using? This line alone won't compile: LPDWORD pKeyType = REG_SZ; <-- error C2440: 'initializing' : cannot convert from 'int' to 'LPDWORD' There's several problems

              HKEY hMyKey;
              long lResult;
              LPDWORD pKeyType = REG_SZ; <-- wrong data type - should be a DWORD It's also an OUT variable (if used correctly) so initializing it is pointless
              LPDWORD pKeySize = 0; <-- wrong data type
              char* strKeyName = "SSSRights";
              char* strKeyVal = "\0"; <-- You need to actually allocate space for the returned characters Had the query actually succeeded, it most likely would have crashed trying to write data to a const character array of length 1.

              jpyp wrote:

              Why do I need the first call to RegQueryValueEx? What does it do?

              It sets KeySize to the number of BYTES required to store the returned string. I use that value to know how big the buffer needs to be, which I allocate on the next line. You could have just allocated an arbitrary number of bytes, but you'd get a truncated string if the registry entry was longer than your buffer. The function is capable of returning the necessary buffer size, so that's the proper way to do it.

              jpyp wrote:

              Why does the first call fail when I provide a buffer instead of NULL?

              Your incorrect use of LPDWORD pKeySize = 0; effectively reults in passing a NULL pointer as the lpcbData parameter in the RegQueryValueEx() call. That is not allowed - the function needs to know how big of a buffer it has to return data in and also needs to be able to set the actual number of bytes placed in the buffer.

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              modified on Thursday, October 16, 2008 4:35 PM

              J 1 Reply Last reply
              0
              • M Mark Salsbery

                What compiler are you using? This line alone won't compile: LPDWORD pKeyType = REG_SZ; <-- error C2440: 'initializing' : cannot convert from 'int' to 'LPDWORD' There's several problems

                HKEY hMyKey;
                long lResult;
                LPDWORD pKeyType = REG_SZ; <-- wrong data type - should be a DWORD It's also an OUT variable (if used correctly) so initializing it is pointless
                LPDWORD pKeySize = 0; <-- wrong data type
                char* strKeyName = "SSSRights";
                char* strKeyVal = "\0"; <-- You need to actually allocate space for the returned characters Had the query actually succeeded, it most likely would have crashed trying to write data to a const character array of length 1.

                jpyp wrote:

                Why do I need the first call to RegQueryValueEx? What does it do?

                It sets KeySize to the number of BYTES required to store the returned string. I use that value to know how big the buffer needs to be, which I allocate on the next line. You could have just allocated an arbitrary number of bytes, but you'd get a truncated string if the registry entry was longer than your buffer. The function is capable of returning the necessary buffer size, so that's the proper way to do it.

                jpyp wrote:

                Why does the first call fail when I provide a buffer instead of NULL?

                Your incorrect use of LPDWORD pKeySize = 0; effectively reults in passing a NULL pointer as the lpcbData parameter in the RegQueryValueEx() call. That is not allowed - the function needs to know how big of a buffer it has to return data in and also needs to be able to set the actual number of bytes placed in the buffer.

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                modified on Thursday, October 16, 2008 4:35 PM

                J Offline
                J Offline
                jpyp
                wrote on last edited by
                #7

                I use Studio 6.0 and you are right it does not compile. I had taken out the initialization before in my code but forgot to take it out in my first post here. I understand now why it wasn't working initially. The size of the buffer must be the same as the value in the last field. I was providing a value of 0 for KeySize because I thought it was a output value only. So only one call is necessary but it is certainly safer to do it your way to get the actual size of the value. As for the wrong data types, I took those directly from the MSDN library help page. Their data type are LPDWORD for the key type and key size fields. Thanks a lot for your help!

                jpyp

                M 1 Reply Last reply
                0
                • J jpyp

                  I use Studio 6.0 and you are right it does not compile. I had taken out the initialization before in my code but forgot to take it out in my first post here. I understand now why it wasn't working initially. The size of the buffer must be the same as the value in the last field. I was providing a value of 0 for KeySize because I thought it was a output value only. So only one call is necessary but it is certainly safer to do it your way to get the actual size of the value. As for the wrong data types, I took those directly from the MSDN library help page. Their data type are LPDWORD for the key type and key size fields. Thanks a lot for your help!

                  jpyp

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #8

                  jpyp wrote:

                  As for the wrong data types, I took those directly from the MSDN library help page. Their data type are LPDWORD for the key type and key size fields.

                  Are you talking about the parameter types for the RegQueryValueEx() function? If so, then yes, that is the type of variable that needs to be passed... that doesn't necessarily mean your variables are supposed to be that type. For example, a parameter with type LPDWORD - if you read the docs for that parameter, you'll see wording like "A pointer to a variable that receives..." or "A pointer to a variable that specifies...". That is NOT what you were passing :)

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups