- SHGetSpecialFolderPath [1] of shell32.dll: works on any system from Win9x to Vista;
- HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\AppData registry variable: is present on any Windows flavor, but marked as deprecated in Vista;
- The APPDATA environment variable: appeared in Windows 2000 and is present on any Windows including Vista.
- Has windir env var;
- Does not have either HOMEDRIVE or HOMEPATH env vars (so the "~" on these systems expands to the name of the system disk drive);
- Does not have either USERPROFILE or APPDATA env vars;
- Has "application data" in %windir%\Application data;
- Supports SHGetSpecialFolderPath;
- Has the aforementioned registry value.
- Doesn't have APPDATA;
- Has insane HOMEDRIVE and HOMEPATH values;
- Has USERPROFILE which holds correct location of the user's "application data" directory;
- Supports SHGetSpecialFolderPath;
- Has the aforementioned registry value.
- Has APPDATA;
- Has sane HOMEDRIVE and HOMEPATH values;
- Has USERPROFILE which usually equals to %HOMEDRIVE%\%HOMEPATH%;
- Supports SHGetSpecialFolderPath;
- Has the aforementioned registry value.
- Same as Windows 2000/XP, but
- The registry key holding "standard folders" locations is marked as deprecated.
- Reading the registry;
- Calling SHGetSpecialFolderPath.
- TWAPI is much larger than Ffidl. This may be a crucial issue when considering what package to put into a starpack, especially if the program is not supposed to use Win32 API beyond the topic we're discussing here;
- TWAPI doesn't work on Win9x/ME.
package require Ffidl
ffidl::callout dll_SHGetSpecialFolderPath \
{int pointer-utf16 int int} int \
[ffidl::symbol shell32.dll SHGetSpecialFolderPathW]
proc SHGetSpecialFolderPath {what create} {
array set CSIDL {
CSIDL_DESKTOP 0
CSIDL_INTERNET 1
CSIDL_PROGRAMS 2
CSIDL_CONTROLS 3
CSIDL_PRINTERS 4
CSIDL_PERSONAL 5
CSIDL_FAVORITES 6
CSIDL_STARTUP 7
CSIDL_RECENT 8
CSIDL_SENDTO 9
CSIDL_BITBUCKET 10
CSIDL_STARTMENU 11
CSIDL_DESKTOPDIRECTORY 16
CSIDL_DRIVES 17
CSIDL_NETWORK 18
CSIDL_NETHOOD 19
CSIDL_FONTS 20
CSIDL_TEMPLATES 21
CSIDL_COMMON_STARTMENU 22
CSIDL_COMMON_PROGRAMS 23
CSIDL_COMMON_STARTUP 24
CSIDL_COMMON_DESKTOPDIRECTORY 25
CSIDL_APPDATA 26
CSIDL_PRINTHOOD 27
CSIDL_LOCAL_APPDATA 28
CSIDL_ALTSTARTUP 29
CSIDL_COMMON_ALTSTARTUP 30
CSIDL_COMMON_FAVORITES 31
CSIDL_INTERNET_CACHE 32
CSIDL_COOKIES 33
!SIDL_HISTORY 34
CSIDL_COMMON_APPDATA 35
CSIDL_WINDOWS 36
CSIDL_SYSTEM 37
CSIDL_PROGRAM_FILES 38
!SIDL_MYPICTURES 39
CSIDL_PROFILE 40
!SIDL_SYSTEMX86 41
CSIDL_PROGRAM_FILESX86 42
CSIDL_PROGRAM_FILES_COMMON 43
!SIDL_PROGRAM_FILES_COMMONX86 44
CSIDL_COMMON_TEMPLATES 45
CSIDL_COMMON_DOCUMENTS 46
CSIDL_COMMON_ADMINTOOLS 47
CSIDL_ADMINTOOLS 48
CSIDL_CONNECTIONS 49
CSIDL_COMMON_MUSIC 53
CSIDL_COMMON_PICTURES 54
CSIDL_COMMON_VIDEO 55
CSIDL_RESOURCES 56
CSIDL_RESOURCES_LOCALIZED 57
CSIDL_COMMON_OEM_LINKS 58
CSIDL_CDBURN_AREA 59
CSIDL_COMPUTERSNEARME 61
# should not probably be here:
CSIDL_FLAG_DONT_VERIFY 0x4000
CSIDL_FLAG_CREATE 0x8000
CSIDL_FLAG_MASK 0xFF00
}
set bCreat [expr {$create ? 1 : 0}]
set path [string repeat \u0000 300] ;# MAX_PATH is actually 260
set ok [dll_SHGetSpecialFolderPath 0 $path $CSIDL($what) $bCreat]
if {$ok} {
set ix [string first \u0000 $path]
if {$ix > 0} {
return [string range $path 0 [expr {$ix - 1}]]
}
} else {
return {}
}
}
puts "appdata: [SHGetSpecialFolderPath CSIDL_APPDATA false]"I'm not sure, but Tk apps may probably want not to ignore the first argument of SHGetSpecialFolderPath (which is the handle of a window to associate any error dialog with (as I understand this)) and provide another argument (or an option) to the wrapper proc for specifying the Tk window. Then the handle of that window may be acquired using "winfo id".Also note that a full-fledged implementation should check the result of creating the Ffidl callout and provide some fall-back way(s) for guessing the required "special folder", i.e. by reading the registry.TODO: describe what's implemented in this respect in the ongoing release of Tkabber.
[passer-by] 2015-05-21 I beg your pardon, but are you spamming? I fail to see what the above line has to do with.
EMJ (2015-05-22) No need for accusations, that line was by the original page author!
Duoas 2008-01-08 Repaired some grammatical errors.
BC - 2009-08-19 02:57:39ActiveState 8.4 and 8.5 (on WinXP) both seem to include a HOME element identical to USERPROFILE
% puts "$env(HOME) $env(USERPROFILE)" C:\Documents and Settings\ben C:\Documents and Settings\ben

