4

On my Windows 7 computer, I created some custom user environment variables (right-click computer > properties > "Advanced system settings" > "Environment Variables..." > "New..." for "User variables for ...") but when I echo them in command prompt it seems to not recognize one. For example, this is what I had:

UTILS_HOME  C:\myUtils
UTILS_WILDFLY  %UTILS_HOME%\wildflyUtils

I added both to the PATH variable in my user variables like this:

PATH  %UTILS_HOME%;%UTILS_WILDFLY%

When I echo the PATH I get this:

C:\mytils;%UTILS_WILDFLY%

I expect that it would expand UTILS_WILDFLY but doesn't. Now if I change the name of UTILS_WILDFLY to JBOSS_8, when I echo the path it'll get expanded. I've tried several names for testing and do not understand why some expand and why some do not. When they do not expand I'm not able to access my scripts in that folder on the command line.

Is there some rule that I don't know about for naming environment variables or is this the way it works and I have to do trial and error until I find one that does work?

There are no typos when trying different names. I created the name for the variable and cut and paste it in the PATH variable to rule that out.

Chuck L
  • 43
  • 5
  • You are aware that every time you change an env variable in the system settings -> ... you need to start a **new** cmd.exe to see the changes properly? – DavidPostill Oct 09 '14 at 19:02
  • Not a duplicate of https://superuser.com/questions/27826/why-cant-windows-handle-an-environment-variable-in-path ; in this case, whether it works or not depends on the name of the environment variable in question. – Harry Johnston Oct 09 '14 at 19:42
  • @DavidPostill Yes I restarted cmd.exe everytime I made a change to the environment variables. – Chuck L Oct 09 '14 at 21:11
  • @HarryJohnston I'm glad you could recreate it, I was hoping someone else could. Thank you for the explanation. I was somewhat on the same track thinking my UTILS_WILDFLY variable needed to come first but didn't put it together about it appearing before PATH. This is NOT a dup of http://superuser.com/questions/27826/why-cant-windows-handle-an-environment-variable-in-path – Chuck L Oct 09 '14 at 21:17
  • I posted [a question](https://superuser.com/questions/1464316/avoid-alphabetical-reading-of-windows-environment-variables/1466418#1466418) on how to circumvent this issue. I myself found a way to do it, posted in an answer there. I would suggest you link to that answer in your question, so others see it clearly (they might miss this comment). I would post the solution here... it will probably benefit the community, but that is usually not well received. – sancho.s ReinstateMonicaCellio Aug 10 '19 at 06:01
  • https://superuser.com/questions/1464316/avoid-alphabetical-reading-of-windows-environment-variables/1466418#1466418 – sancho.s ReinstateMonicaCellio Aug 10 '19 at 06:01

2 Answers2

6

The problem is that you're using recursive expansion, i.e., PATH references UTILS_WILDFLY which itself references UTILS_HOME.

Recursive expansion doesn't always work; presumably that means that it isn't supported, so there's no guarantee that it will ever work - which means you shouldn't use it - but in practice it does work sometimes, hence the confusion.

Specifically, on Windows 7, it works if and only if the variable in the middle of the recursive expansion (UTILS_WILDFLY) appears before the variable being expanded (PATH) in the list of variables in the registry. As it happens, the environment variables are alphabetized.

In your case,

  • UTILS_WILDFLY > PATH, so that doesn't work.

  • JBOSS_8 < PATH, so that does.

PATI won't work, but PATG will.

Harry Johnston
  • 5,754
  • 7
  • 30
  • 55
  • 1
    The key's values are alphabetized by the control panel dialog that sets environment variables. Generally registry values are listed in insertion order. Since these environment-variable values aren't necessarily added by a dialog that keeps them in alphabetic order, I should think it's a bad practice to have one `REG_EXPAND_SZ` value depend on another. There's a stronger guarantee that all `REG_SZ` values are loaded before `REG_EXPAND_SZ`, so that's what I'd use, even if it means the values have redundancies such as storing `C:\myUtils\wildflyUtils` instead of `%UTILS_HOME%\wildflyUtils`. – Eryk Sun Feb 20 '15 at 05:42
  • @eryksun: are you sure? I've never seen registry values in non-alphabetical order. And I don't see how the control panel could change the order of the values anyway, there isn't an API function for that. (Well, it could delete them all and then add them in an order of its choice, but that seems unlikely.) But I agree that depending on recursive expansion is a bad idea. – Harry Johnston Feb 20 '15 at 09:12
  • 4
    Check `reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v *`. Do you get alphabetic order? `reg` is dumping the order straight from [`RegEnumValue`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724865%28v=vs.85%29.aspx), for which the docs inform that "[b]ecause values are not ordered, any new value will have an arbitrary index. This means that the function may return values in any order". In practice it's the insertion order. Deleting all of the existing string values and reinserting the new values is exactly what the environment variable dialog does. – Eryk Sun Feb 20 '15 at 09:31
  • Ah, so regedit is lying to me; should have guessed as much. The environment variable behaviour is bizarre, though; why force the values into alphabetical order? (And what if the control panel is terminated while it's in the middle of doing so?) – Harry Johnston Feb 20 '15 at 09:36
  • It starts with the user environment. It first builds a list of `REG_SZ` and `REG_EXPAND_SZ` values to delete. Then it deletes them. Then it adds the new values and flushes the key. Repeat for the system environment. I suppose it would be 'bad' if the process crashed or was killed in the middle of an update. Thankfully it happens in less than a blink of an eye. – Eryk Sun Feb 20 '15 at 09:43
  • If I use `reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v *`, the values are in alphabetical order. I added a new entry and ran it again to confirm. Do you think some keys behave differently than others? – user74094 Feb 22 '15 at 10:48
  • 1
    @user74094: unlikely; on my system, the values in that key are *not* in alphabetical order. I'm guessing this means that I've never changed system environment variables via the control panel, but it also shows that it isn't the registry that is doing the reordering but (as eryksun explained) the control panel (for some inexplicable reason). – Harry Johnston Feb 22 '15 at 19:57
  • 1
    Ok, getting it now. My system environment variables are in alphabetical order because I clicked "Ok" in the control panel. I added a new `REG_EXPAND_SZ` value called "AAPATH" and true enough, cmd.exe and a `reg query` shows it at the end of the list. Clicking "Ok" on the control panel fixes it into first position. – user74094 Feb 23 '15 at 22:09
0

I've also encountered such question. Although this question is done, I'd like to give a quick workaround for future users.

In my situation, I've created two env variables JAVA_HOME and GRADLE_HOME.

D:\>echo %JAVA_HOME%
D:\Program Files\Java\jdk1.8.0_121

D:\>echo %GRADLE_HOME%
D:\Program Files\gradle-3.5

Then %JAVA_HOME%\bin and %GRADLE%_HOME\bin to Path. But by echo %Path%,

D:\Program Files\Java\jdk1.8.0_121\bin;D:\Program Files\Java\jdk1.8.0_12 1\jre;%GRADLE_HOME%\bin;%GROOVY_HOME%\bin; Same situation.

I've also check the reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v * suggested by @eryksun, the result is alphabetic order. So the answer for the root cause for this question may not be windows expands env var in alphabetic order.

My workaround,

GRADLE_HOME -> GGRADLE_HOME then, change back. GGRADLE_HOME -> GRADLE_HOME

Hope someone proficient in windows can give a explanation for such kind of issues.

caisil
  • 101
  • 1