ENVIRONMENT vs RegQueryValue

Started by Mike Luciuk, July 12, 2013, 11:09:24 AM

Previous topic - Next topic

Mike Luciuk

Hello

Back in the olden days (pre 2000) I started using WinBatch - then I was on other contracts but now I'm back and supporting "applications" which I wrote back in the olden days.

Running 2013B on a Windows 7 machine. I have noticed that either I do not understand the new envirnoment yet and I am misinterpreting Wnbactch Commands or something happening that I cannot explain or get a handle on. The following code is returning "different" results

Code (winbatch) Select
REGROOT = @REGCURRENT
REGSUBKEY = "Environment[GROUPDIR]"
REGVALUEO = RegQueryValue(REGROOT, REGSUBKEY)
ENVIROMEO = Environment("GROUPDIR")


So I am expecting REGVALUEO and ENVIROMEO to be the same, but they are not????

Can you provide any insight or direction, please.

Deana

Please explain what you mean by different results.

Note: On Windows 7, this particular registry key is now the type REG_EXPAND_SZ. So you will need to call RegQueryExpSz instead of RegQueryValue.

Here are my results ( using a different environment variable ) on Windows 7 running as a 32-bit script:

Code (winbatch) Select

REGROOT = @REGCURRENT
REGSUBKEY = "Environment[TMP]"
REGVALUEO = RegQueryExpSZ(REGROOT, REGSUBKEY) ; RESULT = %USERPROFILE%\AppData\Local\Temp
ENVIROMEO = Environment("TMP")                ; RESULT = C:\Users\Username\AppData\Local\Temp


You see the registry key uses an embedded environment variable USERPROFILE, where as the Environment variable does not. This is expected on Windows 7.

I actually recommend using a single function call to ShortCutDir to get the Local AppData path then append the Temp directory name as follows:

Code (winbatch) Select
TMP = ShortCutDir( 'Local AppData', 0 , @TRUE ) : 'Temp\'
Deana F.
Technical Support
Wilson WindowWare Inc.

Mike Luciuk

When I run the code (the results I get are)
Code (winbatch) Select
REGROOT = @REGCURRENT
REGSUBKEY = "Environment[GROUPDIR]"
REGVALUEO = RegQueryValue(REGROOT, REGSUBKEY)    ;Mike's result - Y:\ITM\Srvprov
ENVIROMEO = Environment("GROUPDIR")              ;Mike's result - Y:\ITM\Billing


Looking at the variable via Computer>Properties>Advanced System Settings.Environment Variables I see what is in REGVALUEO.

Anything come to mind?

Deana

I wonder if the issue is because, by default, all WinBatch scripts run elevated ( with a manifest setting highest-available). Try launching a differently manifested version of WinBatch by renaming the script with the extension ".wbt_if". This will run WinBatch using an AsInvoker manifest.

Reference:
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/UAC+Elevation~Level~and~Environment~Varibles.txt
Deana F.
Technical Support
Wilson WindowWare Inc.

Mike Luciuk

It would appear not, or I am not understanding. My script - GoBilling.wbt - it is attached here;

Code (winbatch) Select
;Set up for Billing work
RC = @true
REGROOT = @REGCURRENT
REGSUBKEY = "Environment[GROUPDIR]"
REGVALUEO = RegQueryValue(REGROOT, REGSUBKEY)    ;Mike's result - Y:\ITM\Srvprov
ENVIROMEO = Environment("GROUPDIR")              ;Mike's result - Y:\ITM\Srvprov
NEWVALUE = "Y:\ITM\Billingv3"
RC = RegSetValue(REGROOT, REGSUBKEY, NEWVALUE)
REGVALUEN = RegQueryValue(REGROOT, REGSUBKEY)    ;Mike's result - Y:\ITM\Billingv3
ENVIROMEN = Environment("GROUPDIR")              ;Mike's result - Y:\ITM\Srvprov
Message("RegSetValue","%REGSUBKEY% set to %REGVALUEN% - Done")
exit


I run this script in Studio with the above commented results.

I did try renaming the script GoBilling.wbt_if, ran again in Studio with same (incorrect/unupdated) result.

Am I out to lunch?

Deana

There are both System and User environment variables. This data is stored in the following registry keys on Windows 7:

Code (winbatch) Select
;System Variables
SystemVariable = 'AMDAPPSDKROOT'
sysvar = RegQueryValue( @RegMachine, 'SYSTEM\ControlSet001\Control\Session Manager\Environment[':SystemVariable:']')
Pause('System Variable - Registry', sysvar )
sysvar2 = Environment( SystemVariable )
Pause('System Variable - Environment Function', sysvar2 )

; User Variables
UserVariable = 'DUMDUM'
uservar = RegQueryValue( @RegCurrent, 'Environment[':UserVariable:']')
Pause('User Variable - Registry', uservar )
uservar2 = Environment( UserVariable )
Pause('User Variable - Environment Function', uservar2 )

; Display the Environment for this session
allenv = EnvItemize()
Message("Environment Settings", allenv)


Maybe this code will help you identify which variable you would like to obtain: System or User.

Deana F.
Technical Support
Wilson WindowWare Inc.

Mike Luciuk

Ran your provided script - determined that I want to get the USER environment variable (GROUPDIR)

It (the environment variable I want to see) is not found in "System Variables" - script errors out on the REGQUERYVALUE statement.

It is found in "User Variables" - REGQUERYVALUE and ENVIRONMENT return different values. I Exported my REGISTRY and did a search on the values returned by the two above. The REGQUERYVALUE was found where it was expected -
[HKEY_USERS\S-1-5-21-1708537768-884357618-1417001333-78306\Environment]
"GROUPDIR"="Y:\\ITM\\Billingv3" 

The value returned by ENVIRONMENT (and ENVITEMIZE) cannot be found in the exported registry.

Is it possible that Winbatch is not initializing (reinitializing) some work area properly on starup (possibly because of the way I have it installed or something else) and ENVIRONMENT is not seeing the "fresh" registry entries in that work area??

Deana

As I understand it, on Windows 7, the global variables are stored in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and those for each user in HKEY_USERS\*\Environment, where * denotes the SID of the user.

The system maintains an environment block for each user and one for the computer. The system environment block represents environment variables for all users of the particular computer. A user's environment block represents the environment variables the system maintains for that particular user, including the set of system environment variables.

By default, each process receives a copy of the environment block for its parent process. Typically, this is the environment block for the user who is logged on. This is probably why the environment function isn't returning the non default users environment variable. FO r that you will need to query that specific users subkey in the registry.
Deana F.
Technical Support
Wilson WindowWare Inc.

Mike Luciuk

This partially explains what I am experiencing.

The part I cannot grasp is where is Environment("GROUPDIR") pulling its value from. The name (GROUPDIR) does not exist in the HKLM part of the registry tree and the value  Environment("GROUPDIR") is pulling in cannot be found anywhere in the registry (when I go into REGEDIT or look at the export of the entire registry)??

Reason I am being stuborn about this is that I have many places (100+) in the app I'm working on that currently use Environment() and am trying to avoid having to "convert" all this code over to REGQUERYVALUE before our people are converted over to Windows7. The answer may very well be "suck it up buttercup", but I want to make sure it's not something else.....

Deana

I am not quite sure what is going on. The Environment function in WinBatch merely calls the GetEnvironmentVariable API: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx

The documentation for that function states that it can retrieve either a system environment variable or a user environment variable. On my Windows 7 system, it does successfully read both the User and System variables that you see defined in the { Advanced tab } [Environment Variables] using Sysdm.cpl.

It would seem that if you need to get an environment variable for a user account that is not currently logged in, you will need to use the Registry functions to query the HKEY_USERS\<user>\Environment key.
Deana F.
Technical Support
Wilson WindowWare Inc.

td

Quote from: Mike Luciuk on July 15, 2013, 12:44:41 PM
This partially explains what I am experiencing.

The part I cannot grasp is where is Environment("GROUPDIR") pulling its value from. The name (GROUPDIR) does not exist in the HKLM part of the registry tree and the value  Environment("GROUPDIR") is pulling in cannot be found anywhere in the registry (when I go into REGEDIT or look at the export of the entire registry)??

The 'Environment' function is retrieving the value from the the environment block of the WinBatch process running the script.  That block is inherited from the parent process that started the process running WinBatch.   The parent process is usually either the Explorer.exe or cmd.exe but it could be something else.  It all depends on how you started WinBatch (or your compiled script.)   

So the real question is how did the process starting your script get the environment variables it is passing to WinBatch.  You will have to answer that question for yourself.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Mike Luciuk

I am not sure I'm smart enough to answer how the process started my compiled script or WinBatch. In trying to determine this I tried various ways with varying results.

  • Started WinBatch Navigator from Windows Start - Run a WBT - picked my WBT - Results are correct
  • Started WinBatch Navigator from Windows Start - started Studio - opened my WBT - run/debugged it - Results are correct
  • Started WinBatch Studio from Windows Start - opened my WBT - run/debugged it - Results are correct
  • used WinBatch PopMenu - started Studio - opened my WBT - run/debugged it - Results are not right
  • used WinBatch PopMenu - started Navigator  - Run a WBT - picked my WBT - Results are not right
  • run compiled script - Results are correct

How each of these processes get kicked off, I do not know (Explorer.exe or cmd.exe or something else) - they appear to me to all be .exe's.
It also appears that WinBatch PopMenu is the distinguishing component. Do I have to do (should I have done) something with this component after the install made it available on the systray??

td

PopMenu is no different than any other executable in this regard.  It receives the environment block of the process starting it - Explorer by default.  However, PopMenu is started as part of the login session creation process so Explorer's environment block can be modified by other applications, drivers or services after PopMenu has started but before the session login is finished. This appears to be the case for you.

If you plan on using PopMenu to start your sundry scripts that require your environment variable then you could modify PopMenu's environment block variables to match your needs.  There are several ways to do this but the simplest may be to  be editing the the PopMenu menu file PopMenu.mnw to add code to check and set the variable as needed.  This could be done in either the top section of the menu file or in the section for each menu item  that requires the variable to be correctly set.  Another approach would be to kill and restart PopMenu after the login process has completed but this has some obvious drawbacks. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Mike Luciuk

Thank you - I thought I was going nuts......Understanding is way better.


Thankyou for your assistance and enlightenment.