Get system folder location...

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Hi-Toro.

This will return the actual location of things like 'Program Files', 'My Documents', etc -- you can't assume the user has everything in C: these days! :)

Useful for writing installers (#CSIDL_PROGRAMS), 'Favorites' managers (#CSIDL_FAVORITES), etc...

Code: Select all

; Get system folder location...

#CSIDL_INTERNET = $1
#CSIDL_PROGRAMS = $2
#CSIDL_CONTROLS = $3
#CSIDL_PRINTERS = $4
#CSIDL_PERSONAL = $5 ; Use this instead of CSIDL_MYDOCUMENTS. I don't know why! Ask Microsoft...
#CSIDL_FAVORITES = $6
#CSIDL_STARTUP = $7
#CSIDL_RECENT = $8
#CSIDL_SENDTO = $9
#CSIDL_BITBUCKET = $A
#CSIDL_STARTMENU = $B
#CSIDL_MYDOCUMENTS = $C
#CSIDL_MYMUSIC = $D
#CSIDL_MYVIDEO = $E
#CSIDL_DESKTOPDIRECTORY = $10
#CSIDL_DRIVES = $11
#CSIDL_NETWORK = $12
#CSIDL_NETHOOD = $13
#CSIDL_FONTS = $14
#CSIDL_TEMPLATES = $15
#CSIDL_COMMON_STARTMENU = $16
#CSIDL_COMMON_PROGRAMS = $17
#CSIDL_COMMON_STARTUP = $18
#CSIDL_COMMON_DESKTOPDIRECTORY = $19
#CSIDL_APPDATA = $1A
#CSIDL_PRINTHOOD = $1B
#CSIDL_LOCAL_APPDATA = $1C
#CSIDL_ALTSTARTUP = $1D
#CSIDL_COMMON_ALTSTARTUP = $1E
#CSIDL_COMMON_FAVORITES = $1F
#CSIDL_INTERNET_CACHE = $20
#CSIDL_COOKIES = $21
#CSIDL_HISTORY = $22
#CSIDL_COMMON_APPDATA = $23
#CSIDL_WINDOWS = $24
#CSIDL_SYSTEM = $25
#CSIDL_PROGRAM_FILES = $26
#CSIDL_MYPICTURES = $27
#CSIDL_PROFILE = $28
#CSIDL_SYSTEMX86 = $29
#CSIDL_PROGRAM_FILESX86 = $2A
#CSIDL_PROGRAM_FILES_COMMON = $2B
#CSIDL_PROGRAM_FILES_COMMONX86 = $2C
#CSIDL_COMMON_TEMPLATES = $2D
#CSIDL_COMMON_DOCUMENTS = $2E
#CSIDL_COMMON_ADMINTOOLS = $2F
#CSIDL_ADMINTOOLS = $30
#CSIDL_CONNECTIONS = $31
#CSIDL_COMMON_MUSIC = $35
#CSIDL_COMMON_PICTURES = $36
#CSIDL_COMMON_VIDEO = $37
#CSIDL_RESOURCES = $38
#CSIDL_RESOURCES_LOCALIZED = $39
#CSIDL_COMMON_OEM_LINKS = $3A
#CSIDL_CDBURN_AREA = $3B
#CSIDL_COMPUTERSNEARME = $3D
#CSIDL_FLAG_PER_USER_INIT = $800
#CSIDL_FLAG_NO_ALIAS = $1000
#CSIDL_FLAG_DONT_VERIFY = $4000
#CSIDL_FLAG_CREATE = $8000
#CSIDL_FLAG_MASK = $FF00

Structure ****EMID
    cb.b
    abID.b[1]
EndStructure

Structure ITEMIDLIST
    mkid.****EMID
EndStructure

Procedure.s GetSystemFolder (folder)
    *itemid.ITEMIDLIST = #NULL
    If SHGetSpecialFolderLocation_ (0, folder, @*itemid) = #NOERROR
        location$ = Space (#MAX_PATH)
        If SHGetPathFromIDList_ (*itemid, @location$)
            ProcedureReturn location$
        EndIf
    EndIf
EndProcedure

; D E M O . . .

folder$ = GetSystemFolder (#CSIDL_PERSONAL)
MessageRequester ("Result...", "The 'My Documents' folder is located in " + Chr (34) + folder$ + Chr (34), #MB_ICONINFORMATION)
End

--
See ya,
James L Boyd.
http://www.hi-toro.com/
--
dashunbaba
New User
New User
Posts: 8
Joined: Sun Dec 18, 2011 5:59 pm

Re: Get system folder location...

Post by dashunbaba »

a simpler api is

SHGetSpecialFolderPath_

http://msdn.microsoft.com/en-us/library ... s.85).aspx
User avatar
Bisonte
Addict
Addict
Posts: 1226
Joined: Tue Oct 09, 2007 2:15 am

Re:

Post by Bisonte »

psst ....
BackupUser wrote:Posted: Sun Feb 16, 2003 10:31 pm
;)
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Get system folder location...

Post by Kwai chang caine »

psst ....
:lol:
ImageThe happiness is a road...
Not a destination
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Re:

Post by MachineCode »

Bisonte wrote:psst ....
BackupUser wrote:Posted: Sun Feb 16, 2003 10:31 pm
So what? Why do people think we can't reply to old posts? If new information makes an old tip better, then great!
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Get system folder location...

Post by Kwai chang caine »

If new information makes an old tip better, then great!
Yes you have right, i don't know but perhaps the API not exist at that time "2003"
ImageThe happiness is a road...
Not a destination
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Get system folder location...

Post by MachineCode »

Kwaï chang caïne wrote:perhaps the API not exist at that time "2003"
It sure did:
MSDN wrote:Minimum supported client: Windows 2000 Professional
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Get system folder location...

Post by Kwai chang caine »

I don't know...then it's perhaps the reason of the "Psst" ... :wink: :lol:
ImageThe happiness is a road...
Not a destination
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: Get system folder location...

Post by yrreti »

It's nice that some one thought enough to share some older code that he happened to come across.
We can always learn from it, as it shows different approaches. For instance, If you have Droopys lib
installed. It has the command GetSpecialFolderLocation.
So the following code, is all that is needed.
example:

Code: Select all

#CSIDL_DESKTOPDIRECTORY = $10
#CSIDL_APPDATA = $1A
#CSIDL_PERSONAL = $5
Debug GetSpecialFolderLocation(#CSIDL_COMMON_DESKTOPDIRECTORY)
Debug GetSpecialFolderLocation(#CSIDL_APPDATA)
Debug GetSpecialFolderLocation(#CSIDL_PERSONAL)
User avatar
Bisonte
Addict
Addict
Posts: 1226
Joined: Tue Oct 09, 2007 2:15 am

Re: Get system folder location...

Post by Bisonte »

And to complete this old thread, my used method (from ts-soft) :

Code: Select all

Procedure.s GetSpecialFolder(CSIDL)
  ;> -- Author : ts-soft
  ;> -- german forum
  Protected *itemid.ITEMIDLIST
  Protected location.s = Space(#MAX_PATH)
  
  If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
    If SHGetPathFromIDList_(*itemid, @location)
      CoTaskMemFree_(*itemid)
      If Right(location, 1) <> "\" : location + "\" : EndIf
      ProcedureReturn location
    EndIf
  EndIf
  
EndProcedure
and nearly the whole CSIDL Constants are already defined in PB...
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
jpfez
New User
New User
Posts: 6
Joined: Fri Feb 08, 2013 2:05 am
Location: Spain

Re: Get system folder location...

Post by jpfez »

Sorry For re-bumping an old (ancient) thread. But I found another simpler way.

Code: Select all

; ONLY FOR WINDOWS
; This constants enumeration could be deleted (seems that they are already declared in Purebasic)
Enumeration $1
  #CSIDL_INTERNET
  #CSIDL_PROGRAMS
  #CSIDL_CONTROLS
  #CSIDL_PRINTERS
  #CSIDL_PERSONAL
  #CSIDL_FAVORITES
  #CSIDL_STARTUP
  #CSIDL_RECENT
  #CSIDL_SENDTO
  #CSIDL_BITBUCKET
  #CSIDL_STARTMENU
  #CSIDL_MYDOCUMENTS
  #CSIDL_MYMUSIC
  #CSIDL_MYVIDEO
  #CSIDL_DESKTOPDIRECTORY = $10
  #CSIDL_DRIVES
  #CSIDL_NETWORK
  #CSIDL_NETHOOD
  #CSIDL_FONTS
  #CSIDL_TEMPLATES
  #CSIDL_COMMON_STARTMENU
  #CSIDL_COMMON_PROGRAMS
  #CSIDL_COMMON_STARTUP
  #CSIDL_COMMON_DESKTOPDIRECTORY
  #CSIDL_APPDATA
  #CSIDL_PRINTHOOD
  #CSIDL_LOCAL_APPDATA
  #CSIDL_ALTSTARTUP
  #CSIDL_COMMON_ALTSTARTUP
  #CSIDL_COMMON_FAVORITES
  #CSIDL_INTERNET_CACHE
  #CSIDL_COOKIES
  #CSIDL_HISTORY
  #CSIDL_COMMON_APPDATA
  #CSIDL_WINDOWS
  #CSIDL_SYSTEM
  #CSIDL_PROGRAM_FILES
  #CSIDL_MYPICTURES
  #CSIDL_PROFILE
  #CSIDL_SYSTEMX86
  #CSIDL_PROGRAM_FILESX86
  #CSIDL_PROGRAM_FILES_COMMON
  #CSIDL_PROGRAM_FILES_COMMONX86
  #CSIDL_COMMON_TEMPLATES
  #CSIDL_COMMON_DOCUMENTS
  #CSIDL_COMMON_ADMINTOOLS
  #CSIDL_ADMINTOOLS
  #CSIDL_CONNECTIONS
  #CSIDL_COMMON_MUSIC = $35
  #CSIDL_COMMON_PICTURES
  #CSIDL_COMMON_VIDEO
  #CSIDL_RESOURCES
  #CSIDL_RESOURCES_LOCALIZED
  #CSIDL_COMMON_OEM_LINKS
  #CSIDL_CDBURN_AREA
  #CSIDL_COMPUTERSNEARME = $3D
  #CSIDL_FLAG_PER_USER_INIT = $800
  #CSIDL_FLAG_NO_ALIAS = $1000
  #CSIDL_FLAG_DONT_VERIFY = $4000
  #CSIDL_FLAG_CREATE = $8000
  #CSIDL_FLAG_MASK = $FF00
EndEnumeration

Procedure.s GetFolderPath(FolderID.i)
  Protected FolderPath.s = Space(#MAX_PATH)
  SHGetFolderPath_(#NUL, FolderID, #NUL, #NUL, FolderPath)
  ProcedureReturn FolderPath
EndProcedure

;Now test if it works
Debug GetFolderPath(#CSIDL_COMMON_MUSIC)
MacBook White [ MacOS 10.9 | Ubuntu 12 | Windows 8 ]
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Get system folder location...

Post by IdeasVacuum »

...but be aware that #CSIDL has been retired, it does not work in Windows8.
...this does, coded by GJ-68: http://www.purebasic.fr/english/viewtop ... =5&t=55173
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
jpfez
New User
New User
Posts: 6
Joined: Fri Feb 08, 2013 2:05 am
Location: Spain

Re: Get system folder location...

Post by jpfez »

IdeasVacuum wrote:...but be aware that #CSIDL has been retired, it does not work in Windows8.
...this does, coded by GJ-68: http://www.purebasic.fr/english/viewtop ... =5&t=55173
Thanks for the information and the URL, I didn't know that #CSIDL it's deprecated. I feel kind of dumb.
MacBook White [ MacOS 10.9 | Ubuntu 12 | Windows 8 ]
LinXP
New User
New User
Posts: 7
Joined: Mon May 07, 2018 9:58 am

Re: Get system folder location...

Post by LinXP »

Code: Select all

Procedure.s GetSystemDirectory()
  Protected SystemDirectory.s = Space(#MAX_PATH)
  GetSystemDirectory_(SystemDirectory.s, #MAX_PATH)
  PathAddBackslash_(SystemDirectory.s)
  ProcedureReturn SystemDirectory.s
EndProcedure

Procedure.s GetWindowsDirectory()
  Protected WindowsDirectory.s = Space(#MAX_PATH)
  GetWindowsDirectory_(WindowsDirectory.s, #MAX_PATH)
  PathAddBackslash_(WindowsDirectory.s)
  ProcedureReturn WindowsDirectory.s
EndProcedure

Debug GetSystemDirectory()
Debug GetWindowsDirectory()
Post Reply