[Win32utils-devel] GetTempPath vs GetEnvironmentVariable vs getenv

Berger, Daniel Daniel.Berger at qwest.com
Mon Mar 24 11:32:04 EDT 2008


Hi all,
 
I discovered some interesting quirks with regards to getting environment
variable information on Windows. It's because 'TMP' is considered a
system environment variable, which you can't change with
SetEnvironmentVariable() according to the docs.
 
I also noticed that GetTempPath() returns a full path if you set the
value to a relative path.
 
Here's a little program that demonstrates what I'm talking about:
 
# Compare getenv/putenv, GetEnvironmentVariable/SetEnvironmentVariable
require 'windows/api'
include Windows
 
GetTempPath = API.new('GetTempPath','LP','L')
 
GetEnvironmentVariable = API.new('GetEnvironmentVariable', 'PPL', 'L')
SetEnvironmentVariable = API.new('SetEnvironmentVariable', 'PP', 'B')
 
Getenv = API.new('getenv', 'P', 'P', 'msvcrt')
Putenv = API.new('_putenv', 'P', 'I', 'msvcrt')
 
# ENV
def get_env1(var)
   ENV[var]
end
 
# GetEnvironmentVariable
def get_env2(var)
   buf = 0.chr * 260
   GetEnvironmentVariable.call('TMP', buf, buf.length)
   buf.unpack('A*').first
end
  
# GetTempPath, which looks for 'TMP' first
def get_env3
   buf = 0.chr * 260
   GetTempPath.call(buf.length, buf)
   buf.unpack('A*').first
end
 
# getenv()
def get_env4(var)
   Getenv.call(var)
end
 
puts get_env1('TMP') # C:\DOCUME~1\djberge\LOCALS~1\Temp
puts get_env2('TMP') # C:\DOCUME~1\djberge\LOCALS~1\Temp
puts get_env3        # C:\DOCUME~1\djberge\LOCALS~1\Temp\
puts get_env4('TMP') # C:\DOCUME~1\djberge\LOCALS~1\Temp
 
# Set 'TMP' using Ruby's ENV[]=
ENV['TMP'] = "C:\\foo\\bar"
puts "=" * 40
 
puts get_env1('TMP') # C:\foo\bar
puts get_env2('TMP') # C:\foo\bar
puts get_env3        # C:\foo\bar\
puts get_env4('TMP') # C:\DOCUME~1\djberge\LOCALS~1\Temp - oops
 
# Set 'TMP' using SetEnvironmentVariable
SetEnvironmentVariable.call('TMP', "C:\\zap")
puts "=" * 40
 
puts get_env1('TMP') # C:\zap
puts get_env2('TMP') # C:\zap
puts get_env3        # C:\zap\
puts get_env4('TMP') # C:\DOCUME~1\djberge\LOCALS~1\Temp - oops
 
# Set 'TMP' using putenv
Putenv.call("TMP=C:\\blah")
puts "=" * 40
 
puts get_env1('TMP') # C:\blah
puts get_env2('TMP') # C:\blah
puts get_env3        # C:\blah\
puts get_env4('TMP') # C:\blah - ah, there we go
 
# Set 'TMP' to a relative path
Putenv.call("TMP=dan")
puts "=" * 40
 
puts get_env1('TMP') # dan
puts get_env2('TMP') # dan
puts get_env3        # C:\Documents and Settings\djberge\My
Documents\dan - full
puts get_env4('TMP') # dan

The odd thing about TMP is that my shell value doesn't match the
registry setting. The 'set' output shows:
 
TMP=C:\DOCUME~1\djberge\LOCALS~1\Temp
 
But the registry entry, under
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Environment, is set to:
 
C:\Temp
 
Anyway, just thought I'd share.
 
Regards,
 
Dan


This communication is the property of Qwest and may contain confidential or
privileged information. Unauthorized use of this communication is strictly 
prohibited and may be unlawful.  If you have received this communication 
in error, please immediately notify the sender by reply e-mail and destroy 
all copies of the communication and any attachments.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080324/bed374a4/attachment-0001.html 


More information about the win32utils-devel mailing list