Safe place to store user-defined parameters
-
@fredo6 said:
On my Windows 7,
ENV["TMP"] --> C:\Users\Fred\AppData\Local\Temp
ENV["LOCALAPPDATA"] --> C:\Users\Fred\AppData\Local
So I don't see the short Dos 8.3 notation on my PCBecause your username "Fred" is compatible with the 8.3 annotation. If however the username is "tæst" the the returned value would be:
ENV["TMP"] --> C:\Users\TST~1\AppData\Local\Temp ENV["LOCALAPPDATA"] --> C:\Users\T'st\AppData\Local
As demonstrated by this example: http://sketchucation.com/forums/viewtopic.php?f=180&t=52730&start=60#p482159
So
ENV["LOCALAPPDATA"]
is not safe and will fail.@fredo6 said:
Anyway, since the releasing of my scripts I have been using ENV["TMP"] and I never came across a user having problem with non-ascii username. So maybe very few users do set up their PC with a non-ascii username
That's because ENV["TMP"] returns the path in the short 8.3 format.
I've managed to make Win32 API system calls to get the appdata folder in this format. But I don't see any other way to get this path. For me it's not a big deal because I already ship D. Berger's Win32::API class wrapped under the TT:: namespace in TT_Lib2. But it's not an ideal solution for everyone as it requires bundling a third party library.
-
Thomthom,
Thanks really for all your efforts.
On Win7, LOCALAPPDATA seems to be simply the parent of the Temp folder.
So maybe the solution is to use for local data
File.dirname ENV["TMP"]
, which hopefully will preserve the 8.3 notation.It may even work on Windows XP
[EDIT]from Internet googling, it seems that the temp directory on Xp is %SystemDrive%\Documents and Settings{username}\Local Settings\Temp.
On Windows Vista, 7, 8, the directory is %SystemDrive%\Users{username}\AppData\Local\TempSo the method
File.dirname ENV["TEMP"]
would work on both Widnows systems, provided this callFile.dirname
preserves the Dos8.3 notation.Fredo
-
Under XP:
` ENV['LOCALAPPDATA']
nilENV['APPDATA']
C:\Documents and Settings\XPMUser\Application Data`However - APPDATA != Local AppData - so it's not the correct fallback to make.
ENV variable:
ENV.to_hash { "PROCESSOR_ARCHITECTURE"=>"x86", "HOMEDRIVE"=>"C:", "APPDATA"=>"C:\\Documents and Settings\\XPMUser\\Application Data", "USERPROFILE"=>"C:\\Documents and Settings\\XPMUser", "TMP"=>"C:\\DOCUME~1\\XPMUser\\LOCALS~1\\Temp", "SESSIONNAME"=>"Console", "ProgramFiles"=>"C:\\Program Files", "PROCESSOR_REVISION"=>"1707", "PROCESSOR_LEVEL"=>"6", "CommonProgramFiles"=>"C:\\Program Files\\Common Files", "USERNAME"=>"XPMUser", "PROCESSOR_IDENTIFIER"=>"x86 Family 6 Model 23 Stepping 7, GenuineIntel", "OS"=>"Windows_NT", "FP_NO_HOST_CHECK"=>"NO", "CLIENTNAME"=>"Console", "windir"=>"C:\\WINDOWS", "SystemRoot"=>"C:\\WINDOWS", "PATHEXT"=>".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH", "ALLUSERSPROFILE"=>"C:\\Documents and Settings\\All Users", "USERDOMAIN"=>"VIRTUALXP-IE8", "NUMBER_OF_PROCESSORS"=>"1", "HOMEPATH"=>"\\Documents and Settings\\XPMUser", "TEMP"=>"C:\\DOCUME~1\\XPMUser\\LOCALS~1\\Temp", "SystemDrive"=>"C:", "Path"=>"C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\Program Files\\TortoiseHg\\", "LOGONSERVER"=>"\\\\VIRTUALXP-IE8", "ComSpec"=>"C:\\WINDOWS\\system32\\cmd.exe", "COMPUTERNAME"=>"VIRTUALXP-IE8" }
When I make Win32 calls to get the path from the system I get:
TT::Win32.get_folder_path_ansi( TT::Win32::CSIDL_LOCAL_APPDATA ) C:\Documents and Settings\XPMUser\Local Settings\Application Data
That is the full path. But not that this is an English XP version and the user is "XPMUser" which all contains ASCII characters. When the OS language changes or username changes to contain non-ASCII characters it will fail.
The 8.3 version of the path - that seem to work better for Ruby 1.8 is:
TT::Win32.get_short_folder_path_ansi( TT::Win32::CSIDL_LOCAL_APPDATA ) C:\DOCUME~1\XPMUser\LOCALS~1\APPLIC~1
But one cannot hard code these either.
And the different folder structure also means one cannot go from TEMP path to the local appdata path.
-
Forget LOCALAPPDATA and APPDATA.
What I say is that, if
ENV["TEMP"]
return a DOS8.3 notation, and ifFile.dirname
keeps this Dos8.3 notation, then the root to store the data can be File.dirname(ENV["TEMP"].It happens that:
- On Win7, Vista, Win8, the path calculated with this method will be equivalent to
ENV["LOCALAPPDATA"]
- on WinXP, I am pretty sure that the DOS8.3 notation
C:\\DOCUME~1\\XPMUser\\LOCALS~1
is equivalent to the long notation C:\Documents and Settings\XPMUser\Application Data, which is preciselyENV["APPDATA"]
Fredo
- On Win7, Vista, Win8, the path calculated with this method will be equivalent to
-
@fredo6 said:
- on WinXP, I am pretty sure that the DOS8.3 notation
C:\\DOCUME~1\\XPMUser\\LOCALS~1
is equivalent to the long notation C:\Documents and Settings\XPMUser\Application Data, which is preciselyENV["APPDATA"]
Problems is localization - I think XP used localized names for the paths. Lemme just find my old XP machine with Norwegian language and verify.
- on WinXP, I am pretty sure that the DOS8.3 notation
-
@thomthom said:
Problems is localization - I think XP used localized names for the paths. Lemme just find my old XP machine with Norwegian language and verify.
The script does not really bother as long as
ENV["TEMP"]
andFile.dirname(ENV["TEMP"])
are valid directories with only ASCII characters.Fredo
-
I'll try to check that.
-
@fredo6 said:
- on WinXP, I am pretty sure that the DOS8.3 notation
C:\\DOCUME~1\\XPMUser\\LOCALS~1
is equivalent to the long notation C:\Documents and Settings\XPMUser\Application Data, which is preciselyENV["APPDATA"]
APPDATA under XP is:
C:\Documents and Settings\XPMUser\Application DataC:\DOCUME~1\XPMUser\LOCALS~1
This represent:
C:\Documents and Settings\XPMUser\Local Settings
And Local AppData is
C:\Documents and Settings\XPMUser\Local Settings\Application Data
which is mapped to:
C:\DOCUME~1\XPMUser\LOCALS~1\APPLIC~1
- on WinXP, I am pretty sure that the DOS8.3 notation
-
OK. Thanks for the info.
But
C:\Documents and Settings\XPMUser\Local Settings
can make it as well (possibly I can look for a subfolder Application Data).I keep in mind that the reason of using a path calculation based on
ENV["TEMP"]
is to get a valid path in pure ascii.Actually I am just looking for a location:
- which is writable from Ruby
- which is stable through time
- which is not erased by the system accidentally or intentionally
- possibly which can be pointed to via a pure Ascii characters
Otherwise, the name itself does not matter as the user would have no reason to go there.
So, what's left to do is to check whether
File.dirname(ENV["TEMP"])
maintains the DOS8.3 pure ascii notation.Fredo
-
Norwegian XP - User "Tæst":
` ENV.to_hash
{
"PROCESSOR_ARCHITECTURE"=>"x86",
"HOMEDRIVE"=>"C:",
"CLASSPATH"=>".;C:\Programfiler\Java\jre1.6.0_07\lib\ext\QTJava.zip",
"APPDATA"=>"C:\Documents and Settings\T\221st\Programdata",
"USERPROFILE"=>"C:\Documents and Settings\T\221st",
"TMP"=>"C:\DOCUME~1\TST~1\LOKALE~1\Temp",
"SESSIONNAME"=>"Console",
"ProgramFiles"=>"C:\Programfiler",
"PROCESSOR_REVISION"=>"0d08",
"PROCESSOR_LEVEL"=>"6",
"CommonProgramFiles"=>"C:\Programfiler\Fellesfiler",
"USERNAME"=>"T\221st",
"PROCESSOR_IDENTIFIER"=>"x86 Family 6 Model 13 Stepping 8, GenuineIntel",
"OS"=>"Windows_NT",
"FP_NO_HOST_CHECK"=>"NO",
"windir"=>"C:\WINDOWS",
"SystemRoot"=>"C:\WINDOWS",
"PATHEXT"=>".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH",
"ALLUSERSPROFILE"=>"C:\Documents and Settings\All Users",
"USERDOMAIN"=>"WEEBLE",
"NUMBER_OF_PROCESSORS"=>"1",
"HOMEPATH"=>"\Documents and Settings\T\221st",
"TEMP"=>"C:\DOCUME~1\TST~1\LOKALE~1\Temp",
"SystemDrive"=>"C:",
"QTJAVA"=>"C:\Programfiler\Java\jre1.6.0_07\lib\ext\QTJava.zip",
"Path"=>"C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\PROGRA~1\FELLES~1\SONICS~1\;C:\Programfiler\Fellesfiler\Autodesk Shared\;C:\Programfiler\backburner 2\;C:\Programfiler\Fellesfiler\Roxio Shared\DLLShared;c:\Programfiler\Microsoft SQL Server\90\Tools\binn\;C:\Webdev\MySQL\MySQL Server 4.1\bin;C:\Programfiler\QuickTime\QTSystem\",
"LOGONSERVER"=>"\\WEEBLE",
"ComSpec"=>"C:\WINDOWS\system32\cmd.exe",
"COMPUTERNAME"=>"WEEBLE"
}TT::System.local_data_path
C:\DOCUME~1\TST~1\LOKALE~1\PROGRA~1ENV['TEMP']
C:\DOCUME~1\TST~1\LOKALE~1\TempFile.dirname( ENV['TEMP'] )
C:\DOCUME~1\TST~1\LOKALE~1TT::Win32.get_folder_path_ansi( TT::Win32::CSIDL_LOCAL_APPDATA )
C:\Documents and Settings\Tæst\Lokale innstillinger\ProgramdataTT::Win32.get_short_folder_path_ansi( TT::Win32::CSIDL_LOCAL_APPDATA )
C:\DOCUME~1\TST~1\LOKALE~1\PROGRA~1path = TT::Win32.get_short_folder_path_ansi( TT::Win32::CSIDL_LOCAL_APPDATA )
C:\DOCUME~1\TST~1\LOKALE~1\PROGRA~1File.exist? path
truefile = File.join( path, 'test.txt' )
C:\DOCUME~1\TST~1\LOKALE~1\PROGRA~1/test.txtFile.open( file, 'w' ) { |f| f.puts 'Hello World' }
nilFile.exist? file
trueFile.size file
13`PROGRA~1
in the local appdata folder is just a coincidence as the Norwegian work is very similar to English.C:\Documents and Settings\Tæst\Lokale innstillinger\Programdata
It'd be nice to have this tested on a computer with very different language.
Advertisement