AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

GetEnv: reclaim AHk's variables

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Tue Feb 07, 2006 7:22 am    Post subject: GetEnv: reclaim AHk's variables Reply with quote

The function, GetEnv, permits clearing and restoring all environment variables, and retrieving individual variables. This approach avoids any side-effects of using assumed empty variables with names, which coincide with defined environment variables.

The system calls employed are available with all versions of Windows.

syntax:
    * GetEnv( "", "clear" ) ; clear environment variables
    * GetEnv( "", "restore" ) ; restore environment variables
    * GetEnv( "PATH" ) ; retrieve value assigned to environment variable named "PATH" (case insensitive)


known issues:
    * it is advisable to restore environment variables before using Run commands
    * it is necessary to restore environment variables before running the Reload command


demonstration (tested with Windows XP SP2):
Code:
Random, rv, 0, 0xFFFFFFFF

RunWait, %comspec% /c set > env%rv%.txt
   FileRead, env_before, env%rv%.txt
   MsgBox,
      ( LTrim
         < env_before >`n
         %env_before%
         
         < AHk: env variables >`n
         COMPUTERNAME = %COMPUTERNAME%
         *COMPSPEC = %COMSPEC%
         PATH = %PATH%
         *PROMPT = %PROMPT%
         *PATHEXT = %PATHEXT%
         TEMP = %TEMP%
         TMP = %TMP%
      )
GetEnv( "", "clear" )

FileDelete, env%rv%.txt

RunWait, c:\windows\system32\cmd /c set > env%rv%.txt
   FileRead, env_empty, env%rv%.txt
   MsgBox, %
      ( Join
         "< env_empty >`n"
         env_empty
         "`n`n< AHk: env variables >"
         "`nCOMPUTERNAME = " COMPUTERNAME
         "`n*COMPSPEC = " COMSPEC
         "`nPATH = " PATH
         "`n*PATHEXT = " PATHEXT
         "`n*PROMPT = " PROMPT
         "`nTEMP = " TEMP
         "`nTMP = " TMP
         "`n`n< GetEnv: variables >`n"
         "`nCOMPUTERNAME = " GetEnv( "COMPUTERNAME" )
         "`n*COMPSPEC = " GetEnv( "COMSPEC" )
         "`nPATH = " GetEnv( "PATH" )
         "`n*PATHEXT = " GetEnv( "PATHEXT" )
         "`n*PROMPT = " GetEnv( "PROMPT" )
         "`nTEMP = " GetEnv( "TEMP" )
         "`nTMP = " GetEnv( "TMP" )
      )

GetEnv( "", "restore" )
RunWait, %comspec% /c set > env%rv%.txt
   FileRead, env_after, env%rv%.txt
   MsgBox,
      ( LTrim
         < env_after >`n
         %env_after%
         
         < AHk: env variables >`n
         COMPUTERNAME = %COMPUTERNAME%
         *COMPSPEC = %COMSPEC%
         PATH = %PATH%
         *PATHEXT = %PATHEXT%
         *PROMPT = %PROMPT%
         TEMP = %TEMP%
         TMP = %TMP%
      )

FileDelete, env%rv%.txt

if ( env_before = env_after )
   MsgBox, Environment restored successfully!
else
   MsgBox, Environment restoration failed!
return


function:
Code:
GetEnv( p_name, p_mode="" )
{
   static   table, fields
   
   if ( p_mode = "clear" )
   {
      table = |
      fields = |
   
      pTable := DllCall( "GetEnvironmentStrings" )
      if ( ErrorLevel or !pTable )
      {
         MsgBox, [GetEnv: GetEnvironmentStrings] failed: EL = %ErrorLevel%
         return
      }
      
      index = 1
      offset = 0
      loop,
      {
         len := ReadString( record, pTable, offset, 32767 )
         
         if ( len = 0 )
            break
         else if ( Asc( record ) != 61 )
         {
            StringSplit, field, record, =
         
            DllCall( "SetEnvironmentVariable", "str", field1, "uint", 0 )
         
            table := table record
            fields := fields "|" index "," StrLen( field1 ) "," StrLen( field2 )
            
            index += len
         }

         offset += len+1
      }
      
      StringTrimLeft, table, table, 1
      StringTrimLeft, fields, fields, 2

      DllCall( "FreeEnvironmentStrings", "uint", pTable )
      
      return
   }
   else if ( p_mode = "restore" )
   {
      loop, parse, fields, |
      {
         StringSplit, field, A_LoopField, `,
            
         StringMid, name, table, field1, field2
         StringMid, value, table, field1+field2+1, field3
            
         EnvSet, %name%, %value%
      }
      
      return
   }
   
   old_StringCaseSense := A_StringCaseSense
   StringCaseSense, off
   
   loop, parse, fields, |
   {
      StringSplit, field, A_LoopField, `,
      
      StringMid, name, table, field1, field2
      if ( name = p_name )
      {
         StringMid, value, table, field1+field2+1, field3
         break
      }
   }

   StringCaseSense, %old_StringCaseSense%
   
   return, value
}

ReadString( byref r_string, p_address, p_offset, p_size )
{
   r_string = |
   
   p_address += p_offset

   loop, %p_size%
   {
      if ( *p_address = 0 )
         break
      
      r_string := r_string Chr( *p_address )
      
      p_address++
   }
   
   StringTrimLeft, r_string, r_string, 1
      
   return, StrLen( r_string )
}
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10471

PostPosted: Tue Feb 07, 2006 2:38 pm    Post subject: Reply with quote

Nice solution. Hopefully this limitation in the program will get resolved relatively soon.
Back to top
View user's profile Send private message Send e-mail
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Tue Feb 07, 2006 3:47 pm    Post subject: Reply with quote

How?
I would suggest a directive to prefix or suffix all environment variables with user chosen string. Optional, of course, to preserve backward compatibility.
I find this cleaner that forcefully prefix all user's global variables with something.
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10471

PostPosted: Tue Feb 07, 2006 6:48 pm    Post subject: Reply with quote

As discussed in another topic, the #v1.1 directive will probably turn off automatic retrieval of environment variables. Then there will probably be another option that can override it to turn them back on. That very same option will probably get implemented sooner than #v1.1 so that the environment variable issue can be solved sooner.

Edit: To solve this, v1.0.43.08 introduces the #NoEnv directive, which is recommended for all new scripts.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group