This snippet was completely rewritten after comments made by crazyinsomniac, Corion and Tye in either the chatterbox or in direct reply. The crappy code that they justifiably jeered at has been removed and replaced by this.
END UPDATE
Contains two Win32::API wrappers for finding the windows path as well as the paths of other "special folders". (And yes I am aware that _normally_ $ENV{windir} holds the former value.)
GetWindowsDirectory takes no parameters and returns either "" or the location of the windows directory.
GetSpecialFolderPath takes a list CSIDL names (without the leading CISDL_) and returns
Some of the CSIDL names have duplicates, with a short and long version (this currently applies to the names ending in DIRECTORY, with short form DIR being provided as well.)
Ive only tested the behavior of these subs on a W2k box running AS629 so far.
Comment/criticism/bugfixes welcome!
Yves/Demerphq
use Win32::API; use strict; use warnings; BEGIN { # for static vars. my %CSIDL_Constants = ( # Types are: VF - Virtual Folder| W - From Wine, no MS docs to che +ck against| NT - Avail on NT(+?) only, # Shell32.DLL versions : 4.71 - All IE4.0 | 4.72 - All IE4.01/98 | + 5.0 - W2k/Me+ # Look into ShFolder.dll if you have trouble. # http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/r +eference/functions/shgetspecialfolderpath.asp # Name Value Type Comment/Example +Return # ------------------------------------------------------------- +---------------------------------------------------- DESKTOP => 0x0000, # VF -- Root of namespac +e INTERNET => 0x0001, # VF -- The internet PROGRAMS => 0x0002, # -- C:\Documents and + Settings\username\Start Menu\Programs CONTROLS => 0x0003, # VF -- Icons for contro +l panel PRINTERS => 0x0004, # VF -- Installed Printe +rs PERSONAL => 0x0005, # -- C:\Documents and + Settings\username\My Documents FAVORITES => 0x0006, # -- C:\Documents and + Settings\username\Favorites STARTUP => 0x0007, # -- C:\Documents and + Settings\username\Start Menu\Programs\Startup RECENT => 0x0008, # -- C:\Documents and + Settings\username\Recent SENDTO => 0x0009, # -- C:\Documents and + Settings\username\SendTo BITBUCKET => 0x000a, # VF -- Recycling bin STARTMENU => 0x000b, # -- C:\Documents and + Settings\username\Start Menu MYDOCUMENTS => 0x000c, # W -- ?? MYMUSIC => 0x000d, # -- C:\My Music MYVIDEO => 0x000e, # W -- ?? DESKTOPDIRECTORY => 0x0010, # -- C:\Documents and + Settings\username\Desktop DESKTOPDIR => 0x0010, # -- C:\Documents and + Settings\username\Desktop DRIVES => 0x0011, # VF -- My Computer NETWORK => 0x0012, # VF -- Root of network +namespace hierarchy NETHOOD => 0x0013, # -- C:\Documents and + Settings\username\NetHood FONTS => 0x0014, # VF -- C:\WINNT\Fonts TEMPLATES => 0x0015, # -- Document templat +es COMMON_STARTMENU => 0x0016, # NT -- C:\Documents and + Settings\All Users\Start Menu, COMMON_PROGRAMS => 0x0017, # NT -- C:\Documents and + Settings\All Users\Start Menu\Programs COMMON_STARTUP => 0x0018, # NT -- C:\Documents and + Settings\All Users\Start Menu\Programs\Startup COMMON_DESKTOPDIR => 0x0019, # -- C:\Documents and + Settings\All Users\Desktop COMMON_DESKTOPDIRECTORY => 0x0019, # -- C:\Documents and + Settings\All Users\Desktop APPDATA => 0x001a, # 4.71 -- C:\Documents and + Settings\username\Application Data PRINTHOOD => 0x001b, # -- C:\Documents and + Settings\username\PrintHood LOCAL_APPDATA => 0x001c, # 5.0 -- C:\Documents and + Settings\username\Local Settings\Application Data ALTSTARTUP => 0x001d, # -- nonlocalized sta +rtup group COMMON_ALTSTARTUP => 0x001e, # NT -- All users nonloc +alized startup COMMON_FAVORITES => 0x001f, # NT -- Favorite items INTERNET_CACHE => 0x0020, # 4.72 -- C:\Documents and + Settings\username\Temporary Internet Files COOKIES => 0x0021, # -- C:\Documents and + Settings\username\Cookies HISTORY => 0x0022, # -- Internet History COMMON_APPDATA => 0x0023, # 5.0 -- C:\Documents and + Settings\All Users\Application Data WINDOWS => 0x0024, # 5.0 -- %windir% == %SYS +TEMROOT% == C:\WINNT SYSTEM => 0x0025, # 5.0 -- C:\WINNT\SYSTEM3 +2 PROGRAM_FILES => 0x0026, # 5.0 -- C:\Program Files MYPICTURES => 0x0027, # 5.0 -- C:\Documents and + Settings\username\My Documents\My Pictures PROFILE => 0x0028, # 5.0 -- Users profile fo +lder SYSTEMX86 => 0x0029, # W -- ?? PROGRAM_FILESX86 => 0x002a, # W -- ?? PROGRAM_FILES_COMMON => 0x002b, # 5.0/NT+ -- C:\Program Fi +les\Common PROGRAM_FILES_COMMONX86 => 0x002c, # W -- ?? COMMON_TEMPLATES => 0x002d, # W -- ?? COMMON_DOCUMENTS => 0x002e, # -- C:\Documents and + Settings\All Users\Documents COMMON_ADMINTOOLS => 0x002f, # 5.0 -- MMC Admin tools +dir for all users. ADMINTOOLS => 0x0030, # 5.0 -- MMC Admin tools +directory for user CONNECTIONS => 0x0031, # W -- ?? COMMON_MUSIC => 0x0035, # W -- ?? COMMON_PICTURES => 0x0036, # W -- ?? COMMON_VIDEO => 0x0037, # W -- ?? RESOURCES => 0x0038, # W -- ?? RESOURCES_LOCALIZED => 0x0039, # W -- ?? COMMON_OEM_LINKS => 0x003a, # W -- ?? CDBURN_AREA => 0x003b, # W -- ?? COMPUTERSNEARME => 0x003d, # W -- ?? # FLAG_CREATE 0x8000 # FLAG_DONT_VERIFY 0x4000 # FLAG_MASK 0xff00 # FLAG_NO_ALIAS 0x1000 # FLAG_PER_USER_INIT 0x0800 # FOLDER_MASK 0x00ff ); my $GetWindowsDirectory = Win32::API->new( "KERNEL32", "GetWindowsDirectoryA", [ "P", "N +" ], "N" ); # Returns the windows directory, equiv to %windir% but slightly sa +fer sub GetWindowsDirectory { my $buffer = "\0" x 255; $GetWindowsDirectory->Call( $buffer, length $buffer ); $buffer =~ tr/\0//d; return $buffer; }; my $SHGetSpecialFolderPath = Win32::API->new( "SHELL32", "SHGetSpecialFolderPath", [ "P", " +P", "I", "I" ], "I" ); # Returns the paths of special windows folders, sub GetSpecialFolderPath { my @csidl = @_; @csidl = keys %CSIDL_Constants unless @csidl; my %ret; foreach (@csidl) { my $buffer = "\0" x 255; # Preinit the buffer my $hWnd = ""; # this isnt used (afaict) #0 for no create my $r = $SHGetSpecialFolderPath->Call( $hWnd, $buffer +, $CSIDL_Constants{$_}, 0 ); if ($r) { $buffer =~ tr/\0//d; # remove the \0 chars $ret{$_} = $buffer; # save the result } else { $ret{$_} = undef; } } return %ret if wantarray; return ( @csidl > 1 ) ? \%ret : $ret{ $csidl[0] }; } } # Demo usage # Print out the windir and the special folders... $\ = "\n"; print GetWindowsDirectory(); use Data::Dumper; my %hash = GetSpecialFolderPath(); print Dumper( \%hash );
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Determine Standard Windows Paths
by Corion (Patriarch) on Feb 11, 2002 at 18:45 UTC | |
by demerphq (Chancellor) on Feb 12, 2002 at 15:30 UTC |