cmd.exe environmental variables

  • Thread starter Thread starter JC
  • Start date Start date
J

JC

I've noticed that starting up a new cmd.exe prompt no longer displays the current
environmental variables. Where does cmd.exe get it's ev's from? Is there an API
to call in order to force a Windows cmd.exe prompt to read System EVs from the
registry?

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

All three of these keys display the same values. Yet, when I start up a cmd.exe
prompt, Windows reads OLD values that no longer exist anywhere inside the
registry. The keys were changed last week... and the keys display the proper
values, but a new cmd.exe prompt displays OLD values.

The OS tested is XP Professional SP2.

I've also tried two different cmd.exe prompts, one in the system32 folder and
one in another folder (a copy of that, not a .lnk to it).

I discovered a way to correct it. But something may be wrong, because it
should have taken effect the first time I changed it (I think, or I need to make an
extra API call to force the changes over to a cmd.exe prompt).
1) Right-click upon My Computer, click upon the Advanced tab, click upon
the Environmental Variables button.
2) Click upon the EV that needs to get changed.
3) Change the EV to the appropriate path (I simply added "\." to the path that
already exists there).
4) Click OK to close the Environmental Variables dialog.
5) Click OK to close the System Properties dialog.
6) Open a cmd.exe prompt and take a look at the changed EV.

That corrected it, but it should have been corrected previously, I think. I'm thinking
along the lines that there's a bug when closing one of the dialogs, where Windows
changes the keys in the registry, but somewhere caches the old information and
fails to reflect the changes when opening a new cmd.exe prompt... more testing...

OK. To duplicate the problem and recreate the issue:

1) Open the registry editor.
2) Change any environmental key in
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
3) Go through the steps listed above to verify the key was changed without changing
anything there.
4) Open a cmd.exe prompt.
5) Check the EV you just changed in the registry. You will see that the registry either
did NOT get updated or that the cmd.exe prompt did NOT read from the registry. And
what I see, is that right-clicking upon My Computer does REREAD from the registry,
while starting up a new cmd.exe prompt does not. Even if you CLOSE all existing cmd
prompts and re-open a new prompt, the registry is NOT read.

The steps above indicate:

1) An API call exists to push the changes through so newly opened cmd prompts get
the changes and reflect the changes.
2) The EV's tested above were System Variables as opposed to User Variables. I
did not test User Variables, and currently think that the problem exists when doing
similar changes to User Variables in the registry.
3) It's only a cmd prompt issue, as reading changed keys from the registry reflects the
changes.

I believe this problem also exists in other programming languages, not only VB. So what
happens is if you call a .bat or .cmd script from an application after making changes to
System EVs in the registry (possibly User EVs as well), the .bat or .cmd may NOT reflect
the changed EVs (I have not fully tested this as I recently recognized the problem and I'm
just posting this if anyone wants to check, I'm anticipating other possible problems at the
moment - too late for me to get into this tonight).

NOTE: It's ONLY in starting a new cmd prompt that I see the problem where the EV that
gets displayed in the cmd prompt reflects an OLD EV that was changed through via a
call to the registry.

Hope the information here helps others correct EV problems with the cmd.exe prompt.
And one last thing, can anyone else duplicate the problem with other Microsoft OS's?
 
I've noticed that starting up a new cmd.exe prompt no longer displays the
current
environmental variables. Where does cmd.exe get it's ev's from? Is there an
API
to call in order to force a Windows cmd.exe prompt to read System EVs from
the
registry?

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

All three of these keys display the same values. Yet, when I start up a
cmd.exe
prompt, Windows reads OLD values that no longer exist anywhere inside the
registry. The keys were changed last week... and the keys display the proper
values, but a new cmd.exe prompt displays OLD values.

The OS tested is XP Professional SP2.

I've also tried two different cmd.exe prompts, one in the system32 folder
and
one in another folder (a copy of that, not a .lnk to it).

I discovered a way to correct it. But something may be wrong, because it
should have taken effect the first time I changed it (I think, or I need
to make an
extra API call to force the changes over to a cmd.exe prompt).
1) Right-click upon My Computer, click upon the Advanced tab, click upon
the Environmental Variables button.
2) Click upon the EV that needs to get changed.
3) Change the EV to the appropriate path (I simply added "\." to the path
that
already exists there).
4) Click OK to close the Environmental Variables dialog.
5) Click OK to close the System Properties dialog.
6) Open a cmd.exe prompt and take a look at the changed EV.

That corrected it, but it should have been corrected previously, I think.
I'm thinking
along the lines that there's a bug when closing one of the dialogs, where
Windows
changes the keys in the registry, but somewhere caches the old information
and
fails to reflect the changes when opening a new cmd.exe prompt... more
testing...

OK. To duplicate the problem and recreate the issue:

1) Open the registry editor.
2) Change any environmental key in
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
3) Go through the steps listed above to verify the key was changed without
changing
anything there.
4) Open a cmd.exe prompt.
5) Check the EV you just changed in the registry. You will see that the
registry either
did NOT get updated or that the cmd.exe prompt did NOT read from the
registry. And
what I see, is that right-clicking upon My Computer does REREAD from the
registry,
while starting up a new cmd.exe prompt does not. Even if you CLOSE all
existing cmd
prompts and re-open a new prompt, the registry is NOT read.

The steps above indicate:

1) An API call exists to push the changes through so newly opened cmd
prompts get
the changes and reflect the changes.
2) The EV's tested above were System Variables as opposed to User Variables.
I
did not test User Variables, and currently think that the problem exists
when doing
similar changes to User Variables in the registry.
3) It's only a cmd prompt issue, as reading changed keys from the registry
reflects the
changes.

I believe this problem also exists in other programming languages, not only
VB. So what
happens is if you call a .bat or .cmd script from an application after
making changes to
System EVs in the registry (possibly User EVs as well), the .bat or .cmd may
NOT reflect
the changed EVs (I have not fully tested this as I recently recognized the
problem and I'm
just posting this if anyone wants to check, I'm anticipating other possible
problems at the
moment - too late for me to get into this tonight).

NOTE: It's ONLY in starting a new cmd prompt that I see the problem where
the EV that
gets displayed in the cmd prompt reflects an OLD EV that was changed through
via a
call to the registry.

Hope the information here helps others correct EV problems with the cmd.exe
prompt.
And one last thing, can anyone else duplicate the problem with other
Microsoft OS's?

--
Jim Carlock
More Than Five Senses
http://www.associatedcontent.com/article/381163/more_than_five_senses.html

============

What is the point of changing EVs by a registry hack if there are approved
and published methods of changing them directly?
- Using "set" as a console command to change them for the current process;
- Using setx.exe to change the master EV table.
Setx.exe comes with the Windows Resource Kit.
 
Pegasus (MVP) said:
I've noticed that starting up a new cmd.exe prompt no longer displays the
current
environmental variables. Where does cmd.exe get it's ev's from? Is there
an API
to call in order to force a Windows cmd.exe prompt to read System EVs from
the
registry?

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

All three of these keys display the same values. Yet, when I start up a
cmd.exe
prompt, Windows reads OLD values that no longer exist anywhere inside the
registry. The keys were changed last week... and the keys display the
proper
values, but a new cmd.exe prompt displays OLD values.

The OS tested is XP Professional SP2.

I've also tried two different cmd.exe prompts, one in the system32 folder
and
one in another folder (a copy of that, not a .lnk to it).

I discovered a way to correct it. But something may be wrong, because it
should have taken effect the first time I changed it (I think, or I need
to make an
extra API call to force the changes over to a cmd.exe prompt).
1) Right-click upon My Computer, click upon the Advanced tab, click upon
the Environmental Variables button.
2) Click upon the EV that needs to get changed.
3) Change the EV to the appropriate path (I simply added "\." to the
path that
already exists there).
4) Click OK to close the Environmental Variables dialog.
5) Click OK to close the System Properties dialog.
6) Open a cmd.exe prompt and take a look at the changed EV.

That corrected it, but it should have been corrected previously, I think.
I'm thinking
along the lines that there's a bug when closing one of the dialogs, where
Windows
changes the keys in the registry, but somewhere caches the old information
and
fails to reflect the changes when opening a new cmd.exe prompt... more
testing...

OK. To duplicate the problem and recreate the issue:

1) Open the registry editor.
2) Change any environmental key in
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
3) Go through the steps listed above to verify the key was changed without
changing
anything there.
4) Open a cmd.exe prompt.
5) Check the EV you just changed in the registry. You will see that the
registry either
did NOT get updated or that the cmd.exe prompt did NOT read from the
registry. And
what I see, is that right-clicking upon My Computer does REREAD from the
registry,
while starting up a new cmd.exe prompt does not. Even if you CLOSE all
existing cmd
prompts and re-open a new prompt, the registry is NOT read.

The steps above indicate:

1) An API call exists to push the changes through so newly opened cmd
prompts get
the changes and reflect the changes.
2) The EV's tested above were System Variables as opposed to User
Variables. I
did not test User Variables, and currently think that the problem exists
when doing
similar changes to User Variables in the registry.
3) It's only a cmd prompt issue, as reading changed keys from the registry
reflects the
changes.

I believe this problem also exists in other programming languages, not
only VB. So what
happens is if you call a .bat or .cmd script from an application after
making changes to
System EVs in the registry (possibly User EVs as well), the .bat or .cmd
may NOT reflect
the changed EVs (I have not fully tested this as I recently recognized the
problem and I'm
just posting this if anyone wants to check, I'm anticipating other
possible problems at the
moment - too late for me to get into this tonight).

NOTE: It's ONLY in starting a new cmd prompt that I see the problem where
the EV that
gets displayed in the cmd prompt reflects an OLD EV that was changed
through via a
call to the registry.

Hope the information here helps others correct EV problems with the
cmd.exe prompt.
And one last thing, can anyone else duplicate the problem with other
Microsoft OS's?

--
Jim Carlock
More Than Five Senses
http://www.associatedcontent.com/article/381163/more_than_five_senses.html

============

What is the point of changing EVs by a registry hack if there are approved
and published methods of changing them directly?
- Using "set" as a console command to change them for the current process;
- Using setx.exe to change the master EV table.
Setx.exe comes with the Windows Resource Kit.

I created a new variable in the registry. It showed up in "my computer -
properties - advanced - environment variables", but did not show up in the
next cmd.exe window I opened. But it did show up after the next reboot.
Seems to me that the purpose of "my computer - properties - advanced -
environment variables" is to pre-set variables at boot time. For that it
seems to work fine.

/Al
 
JC said:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

Use "CurrentControlSet", which actually points to one of the keys that start
with numbers. This is not necessarily ControlSet001, which is usually the
first to show up in a registry search. The actual configuration key that
"CurrentControlSet" points to is located at the following location:

HKEY_LOCAL_MACHINE\SYSTEM\Select\Current

Off course, if there is a documented way, use the documented way instead of
the undocumented way. VB6 has Environ() Function, and the API equivalent are
GetEnvironmentStrings() and GetEnvironmentVariable().
 
I created a new variable in the registry.

Really bad way to do it...
It showed up in "my computer -
properties - advanced - environment variables",
Non-sequitor

but did not show up in the
next cmd.exe window I opened.

It would have had you rebooted the computer. The hive had already been
loaded, and since Windows does not know you hacked the registry
manually, it doesn't knwo to reload it.
But it did show up after the next reboot.
Yep!

Seems to me that the purpose of "my computer - properties - advanced -
environment variables" is to pre-set variables at boot time. For that it
seems to work fine.

I'm confused as to what you hope to accomplish. You are hacking the
registry, then getting confused when Windows doesn't know you hacked
the registry, and for what? use the approved and provided interface(s)
and things will work so much better.
 
: I'm confused as to what you hope to accomplish. You are hacking the
: registry, then getting confused when Windows doesn't know you hacked
: the registry, and for what? use the approved and provided interface(s)
: and things will work so much better.

I asked for responces from others. It was late last night when I made a
post requesting some confirmation about other operating systems, as it
helps when looking for the proper ways to do things. Al Dunbar provided
a reply in that regards, I believe, but only Al knows for sure. <g>

Peter, if you might relay your "approved and provided interface(s)" for
the benefit of the community at large, we all might benefit.

If you re-read the thread, and take some time trying to understand my
initial requests, you'll see that I identified that newly opened cmd.exe
prompts (in Windows XP SP2) do NOT recognize changes in the following
keys:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

I posted all of those keys to document that even though ALL three of the
keys held the same values (I don't think I stated that though), a new
cmd.exe prompt still did NOT reflect any changes (when some changes are
made in the registry). And it was late last night and while trying to
identify the problem myself, I posted more detail than I desired posting.
I believe the information I asked for, and the details provided were
fairly accurate and easy to understand, although I could be wrong about
that.

I notated that I changed the keys via (Microsoft documented ways to
change such "System Environmental Variables") and noticed when employing
that method, the newly opened cmd.exe prompts DO reflect the changes. I
hope this helps further identify what I want to accomplish.

"Pegasus (MVP)" <[email protected]> suggested...
: What is the point of changing EVs by a registry hack if there are
: approved and published methods of changing them directly?
: - Using "set" as a console command to change them for the current process;
: - Using setx.exe to change the master EV table.
: Setx.exe comes with the Windows Resource Kit.

Thanks for mentioning setx.exe, Pegasus. It provided some additional ways
to find what I needed. I figured that a call to the SendMessage() provided
what I was seeking, and looking at the IMPORTS for setx.exe reveals that
instead of SendMessageA() it employs another API, SendMessageTimeoutA().

Searching live.com for SendMessageTimeoutA turned up some extra things to
dig through.

The source code below, I place in the public domain.

Option Explicit

Private Const WM_SETTINGCHANGE As Long = &H1A&
Private Const WM_WININICHANGE As Long = &H1A&
Private Const HWND_BROADCAST As Long = &HFFFF&
' SendMessageTimeout values
Private Enum eSMTO_Flags
SMTO_NORMAL = &H0&
SMTO_BLOCK = &H1&
SMTO_ABORTIFHUNG = &H2&
End Enum

Private Declare Function SendMessageA Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function SendMessageTimeoutA Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal msg As Long, _
ByVal wParam As Long, _
lParam As Any, _
ByVal eSMTO_Flags As Long, _
ByVal uTimeout As Long, _
lpdwResult As Long) As Long
Private Declare Function GetLastError Lib "kernel32.dll" () As Long

'GOAL (1)
' Recognize changes in newly opened cmd.exe prompts.
' SUCCESS
'GOAL (2)
' Try to get existing cmd.exe prompts to recognize registry changes.
' FAILED
Private Sub Main()
Dim dwResult As Long, dwSuccess As Long, dwSDTO As eSMTO_Flags

dwSDTO = SMTO_NORMAL Or SMTO_ABORTIFHUNG
dwResult = &HFFFFFFFF

'
'NOTE
' No error gets returned.
' Old cmd.exe prompts do not get updated.
' Newly opened cmd.exe prompts reflect proper system environmental variables.
' ByVal is required in front of the word "Environment"
' ALSO
' Take note of the wParam and the lpdwResult set as &HFFFFFFFF and NOT 0&.
' When they are both set to 0&, the desired result does NOT show up.
dwSuccess = SendMessageTimeoutA(HWND_BROADCAST, _
WM_SETTINGCHANGE, _
&HFFFFFFFF, _
ByVal "Environment", _
dwSDTO, _
1000&, _
&HFFFFFFFF)

'NOTE
' Not sure what the string "Windows" does, but found a link where Tom Esh
' references and another reference it:
' microsoft.public.vb.winapi (2005-11)
' See Also
' http://msdn.microsoft.com/en-us/library/ms644952.aspx
' The string, "Windows", changes nothing. No error returned.
'dwSuccess = SendMessageTimeoutA(_
' HWND_BROADCAST, _
' WM_SETTINGCHANGE, _
' &HFFFFFFFF, _
' ByVal "Windows", _
' dwSDTO, _
' 1000&, _
' &HFFFFFFFF)

'
'NOTE
' No error gets returned. Nothing changes.
' Opening a new cmd.exe prompt does NOT reflect changes in the registry.
'
'dwSuccess = SendMessageTimeoutA( _
' HWND_BROADCAST, _
' WM_WININICHANGE, _
' &H0&, _
' ByVal "Environment", _
' dwSDTO, _
' 1000&, _
' &H0&)
'

Call MsgBox(Err.LastDllError, vbOKOnly, "Err.LastDllError")
Call MsgBox(CStr(dwSuccess), vbOKOnly, "dwSuccess")
End Sub

The source code above achieves getting newly opened cmd.exe prompts to
recognizes changes applied to the registry. The comments in it should
help others. Anyone is welcome to comment and any help is appreciated.
I would still like to get existing cmd.exe prompts to recognize changes.

Even though Tom Esh did not reply in this thread, I give thanks to Tom
for a previous thread. He used 0 values for the wParam and lpdwResult
parameters which did not work as expected.

I'd like to thank Pegasus for mentioning the setx.exe application. As
digging through that application revealed the use of &HFFFFFFFF for
those two variables, although I am not sure why, but that's the way
the SendMessageTimeoutA() gets called inside of that file. And so I
kind of stumbled upon those two values (which may or may not be correct,
but they work where the values of 0 do not).

56 PUSH ESI ; /pResult = FFFFFFFF
68 E8030000 PUSH 3E8 ; |Timeout = 1000. ms
6A 02 PUSH 2 ; |Flags = SMTO_NORMAL|SMTO_ABORTIFHUNG
68 E4100001 PUSH setx.010010E4 ; |lParam = 10010E4
56 PUSH ESI ; |wParam = FFFFFFFF
6A 1A PUSH 1A ; |Message = WM_WININICHANGE
68 FFFF0000 PUSH 0FFFF ; |hWnd = 0000FFFF
FF15 80100001 CALL DWORD PTR DS:[<&USER32.SendMessageTimeoutA>] ; \SendMessageTimeoutA

lParam pointed to an ASCII string "Environment"

I placed the VB code above into a module so it's a GUI-less program.

To test the code out:

(1) Open a cmd.exe prompt up. Keep this cmd.exe prompt open at all times.
(2) Compile the VB source code above to create a Standard EXE.
(3) Open the registry editor.
(4) Navigate to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
(5) Add a new environmental variable there (REG_SZ) and give it a value.
(6) Type in SET [ev_name] to see if the already opened cmd.exe prompt
recognizes it.
(7) Start a new cmd prompt up and check to see if the EV you entered in
the registry exists in the new cmd prompt. (It should not exist yet.)
(8) Close the new cmd prompt.
(9) Double-click upon the application you compiled, it should present two
message boxes with a slight pause between them.
(10) Check the EV in the old cmd prompt you left open. It does not exist.
Please post back if you obtain different results.
(11) Open a new cmd prompt and check the EV in the new cmd prompt. The
new cmd prompt should recognize the EV and display it.
(12) Close the cmd prompt, delete the EV you configured in the registry.
Or if you wish to play around with things... hope this helps.

Please post back with any problems or contradictions. I'm interested in
how it works out in other operating systems as well. I tested the above
with Windows XP SP2.

Thanks again to everyone that replied.
 
PeterD said:
Really bad way to do it...

Not if my purpose is illustrative...
It would have had you rebooted the computer. The hive had already been
loaded, and since Windows does not know you hacked the registry
manually, it doesn't knwo to reload it.

Exactly my point.

Exactly my point.
I'm confused as to what you hope to accomplish.

Obviously. I am not the one hoping to accomplish anything. What you were
replying to was my response to the OP, in which I was telling him basically
what you are trying to tell me.
You are hacking the
registry, then getting confused when Windows doesn't know you hacked
the registry, and for what? use the approved and provided interface(s)
and things will work so much better.

I'd agree completely, if only you'd direct your comments to the OP.

/Al
 
: I'm confused as to what you hope to accomplish. You are hacking the
: registry, then getting confused when Windows doesn't know you hacked
: the registry, and for what? use the approved and provided interface(s)
: and things will work so much better.

I asked for responces from others. It was late last night when I made a
post requesting some confirmation about other operating systems, as it
helps when looking for the proper ways to do things. Al Dunbar provided
a reply in that regards, I believe, but only Al knows for sure. <g>


===> LOL. apparently I did not make my intentions clear in my reply...

/Al


Peter, if you might relay your "approved and provided interface(s)" for
the benefit of the community at large, we all might benefit.

If you re-read the thread, and take some time trying to understand my
initial requests, you'll see that I identified that newly opened cmd.exe
prompts (in Windows XP SP2) do NOT recognize changes in the following
keys:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment
HKLM\SYSTEM\ControlSet002\Control\Session Manager\Environment

I posted all of those keys to document that even though ALL three of the
keys held the same values (I don't think I stated that though), a new
cmd.exe prompt still did NOT reflect any changes (when some changes are
made in the registry). And it was late last night and while trying to
identify the problem myself, I posted more detail than I desired posting.
I believe the information I asked for, and the details provided were
fairly accurate and easy to understand, although I could be wrong about
that.

I notated that I changed the keys via (Microsoft documented ways to
change such "System Environmental Variables") and noticed when employing
that method, the newly opened cmd.exe prompts DO reflect the changes. I
hope this helps further identify what I want to accomplish.

"Pegasus (MVP)" <[email protected]> suggested...
: What is the point of changing EVs by a registry hack if there are
: approved and published methods of changing them directly?
: - Using "set" as a console command to change them for the current process;
: - Using setx.exe to change the master EV table.
: Setx.exe comes with the Windows Resource Kit.

Thanks for mentioning setx.exe, Pegasus. It provided some additional ways
to find what I needed. I figured that a call to the SendMessage() provided
what I was seeking, and looking at the IMPORTS for setx.exe reveals that
instead of SendMessageA() it employs another API, SendMessageTimeoutA().

Searching live.com for SendMessageTimeoutA turned up some extra things to
dig through.

The source code below, I place in the public domain.

Option Explicit

Private Const WM_SETTINGCHANGE As Long = &H1A&
Private Const WM_WININICHANGE As Long = &H1A&
Private Const HWND_BROADCAST As Long = &HFFFF&
' SendMessageTimeout values
Private Enum eSMTO_Flags
SMTO_NORMAL = &H0&
SMTO_BLOCK = &H1&
SMTO_ABORTIFHUNG = &H2&
End Enum

Private Declare Function SendMessageA Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function SendMessageTimeoutA Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal msg As Long, _
ByVal wParam As Long, _
lParam As Any, _
ByVal eSMTO_Flags As Long, _
ByVal uTimeout As Long, _
lpdwResult As Long) As Long
Private Declare Function GetLastError Lib "kernel32.dll" () As Long

'GOAL (1)
' Recognize changes in newly opened cmd.exe prompts.
' SUCCESS
'GOAL (2)
' Try to get existing cmd.exe prompts to recognize registry changes.
' FAILED
Private Sub Main()
Dim dwResult As Long, dwSuccess As Long, dwSDTO As eSMTO_Flags

dwSDTO = SMTO_NORMAL Or SMTO_ABORTIFHUNG
dwResult = &HFFFFFFFF

'
'NOTE
' No error gets returned.
' Old cmd.exe prompts do not get updated.
' Newly opened cmd.exe prompts reflect proper system environmental
variables.
' ByVal is required in front of the word "Environment"
' ALSO
' Take note of the wParam and the lpdwResult set as &HFFFFFFFF and NOT
0&.
' When they are both set to 0&, the desired result does NOT show up.
dwSuccess = SendMessageTimeoutA(HWND_BROADCAST, _
WM_SETTINGCHANGE, _
&HFFFFFFFF, _
ByVal "Environment", _
dwSDTO, _
1000&, _
&HFFFFFFFF)

'NOTE
' Not sure what the string "Windows" does, but found a link where Tom Esh
' references and another reference it:
' microsoft.public.vb.winapi (2005-11)
' See Also
' http://msdn.microsoft.com/en-us/library/ms644952.aspx
' The string, "Windows", changes nothing. No error returned.
'dwSuccess = SendMessageTimeoutA(_
' HWND_BROADCAST, _
' WM_SETTINGCHANGE, _
' &HFFFFFFFF, _
' ByVal "Windows", _
' dwSDTO, _
' 1000&, _
' &HFFFFFFFF)

'
'NOTE
' No error gets returned. Nothing changes.
' Opening a new cmd.exe prompt does NOT reflect changes in the registry.
'
'dwSuccess = SendMessageTimeoutA( _
' HWND_BROADCAST, _
' WM_WININICHANGE, _
' &H0&, _
' ByVal "Environment", _
' dwSDTO, _
' 1000&, _
' &H0&)
'

Call MsgBox(Err.LastDllError, vbOKOnly, "Err.LastDllError")
Call MsgBox(CStr(dwSuccess), vbOKOnly, "dwSuccess")
End Sub

The source code above achieves getting newly opened cmd.exe prompts to
recognizes changes applied to the registry. The comments in it should
help others. Anyone is welcome to comment and any help is appreciated.
I would still like to get existing cmd.exe prompts to recognize changes.

Even though Tom Esh did not reply in this thread, I give thanks to Tom
for a previous thread. He used 0 values for the wParam and lpdwResult
parameters which did not work as expected.

I'd like to thank Pegasus for mentioning the setx.exe application. As
digging through that application revealed the use of &HFFFFFFFF for
those two variables, although I am not sure why, but that's the way
the SendMessageTimeoutA() gets called inside of that file. And so I
kind of stumbled upon those two values (which may or may not be correct,
but they work where the values of 0 do not).

56 PUSH ESI ; /pResult
= FFFFFFFF
68 E8030000 PUSH 3E8 ; |Timeout
= 1000. ms
6A 02 PUSH 2 ; |Flags =
SMTO_NORMAL|SMTO_ABORTIFHUNG
68 E4100001 PUSH setx.010010E4 ; |lParam =
10010E4
56 PUSH ESI ; |wParam =
FFFFFFFF
6A 1A PUSH 1A ; |Message
= WM_WININICHANGE
68 FFFF0000 PUSH 0FFFF ; |hWnd =
0000FFFF
FF15 80100001 CALL DWORD PTR DS:[<&USER32.SendMessageTimeoutA>] ;
\SendMessageTimeoutA

lParam pointed to an ASCII string "Environment"

I placed the VB code above into a module so it's a GUI-less program.

To test the code out:

(1) Open a cmd.exe prompt up. Keep this cmd.exe prompt open at all times.
(2) Compile the VB source code above to create a Standard EXE.
(3) Open the registry editor.
(4) Navigate to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
(5) Add a new environmental variable there (REG_SZ) and give it a value.
(6) Type in SET [ev_name] to see if the already opened cmd.exe prompt
recognizes it.
(7) Start a new cmd prompt up and check to see if the EV you entered in
the registry exists in the new cmd prompt. (It should not exist yet.)
(8) Close the new cmd prompt.
(9) Double-click upon the application you compiled, it should present two
message boxes with a slight pause between them.
(10) Check the EV in the old cmd prompt you left open. It does not exist.
Please post back if you obtain different results.
(11) Open a new cmd prompt and check the EV in the new cmd prompt. The
new cmd prompt should recognize the EV and display it.
(12) Close the cmd prompt, delete the EV you configured in the registry.
Or if you wish to play around with things... hope this helps.

Please post back with any problems or contradictions. I'm interested in
how it works out in other operating systems as well. I tested the above
with Windows XP SP2.

Thanks again to everyone that replied.
 
Back
Top