Best place for user data files (vista and before)

Just starting out? Need help? Post your questions and find answers here.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

You might find these pretty useful.

Code: Select all

Procedure.s GetKeyValue(topKey.l,sKey$,sValue$)
 Protected lType.l,lpcbData.l,hKey.l,lpData$,path$
 lpData$=Space(2048+1)
 lpcbData=Len(lpData$)-1
 If RegOpenKeyEx_(topKey,sKey$,#Null,#KEY_READ,@hKey)=#ERROR_SUCCESS
  RegQueryValueEx_(hKey,sValue$,#Null,@lType,@lpData$,@lpcbData)
  RegCloseKey_(hKey)
 EndIf
 ProcedureReturn Trim(lpData$)
EndProcedure

Procedure.s SpecialFolderLocation(csidl.l)
 Protected location$,pidl.l
 If SHGetSpecialFolderLocation_(#Null,csidl,@pidl)=#ERROR_SUCCESS
  location$=Space(#MAX_PATH)
  If SHGetPathFromIDList_(pidl,@location$)
   If Right(location$,1)<>"\"
    location$+"\"
   EndIf
  EndIf
  If pidl
   CoTaskMemFree_(pidl) ;Instead of messing with com imalloc free and whatnot.
  EndIf
 EndIf
 ProcedureReturn Trim(location$)
EndProcedure

Procedure.s GetProgramFilesDir()
 Protected os.l,value$,path$
 os=OSVersion()
 If os>#PB_OS_Windows_ME
  path$=SpecialFolderLocation(#CSIDL_PROGRAM_FILES)
 Else
  value$=GetKeyValue(#HKEY_LOCAL_MACHINE,"Software\Microsoft\Windows\Currentversion","ProgramFilesDir")
  If value$<>""
   path$=value$
   If Right(value$,1)<>"\"
    path$+"\"
   EndIf
  EndIf
 EndIf
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetApplicationDataDirectory()
 Protected path$
 path$=SpecialFolderLocation(#CSIDL_APPDATA)
 If path$="" ;Needed since Windows 95 do not support CSIDL_APPDATA "out of the box".
  path$=GetProgramFilesDir()+"Application Data\"
 EndIf
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetMyDocumentsDirectory()
 Protected path$
 path$=SpecialFolderLocation(#CSIDL_PERSONAL) ;My Documents\ folder, use this rather than the other CSIDL
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetTempDirectory()
 Protected path$,pathlen.l,result.l
 path$=Space(2048+1)
 result=GetTempPath_(Len(path$)-1,@path$)
 If (result=0) Or (result>Len(path$))
  path$=""
 Else
  If Right(path$,1)<>"\"
   path$+"\"
  EndIf
  If FileSize(path$)<>-2
   If CreateDirectory(path$)=#False
    path$=""
   EndIf
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure
GetProgramFilesDir() ;For example C:\Program Files\
Typically the default install location for programs.
Make sure to use \Company\Appname\ as a common courtesy.

GetApplicationDataDirectory() ;For example C:\Documents and Settings\username\Application Data\
The advised place to put program settings and such files.
Make sure to do the nice \Company\Appname\ thing here too :)

GetMyDocumentsDirectory() ;For example C:\Documents and Settings\username\My Documents\
The advised place to put documents, game save files, etc.
Make sure to do the nice \Company\Appname\ thing here too :)

GetTempDirectory() ;For example C:\Documents and Settings\username\Local Settings\Temp\
The advised place to put temporary files.
Make sure the filename is pretty unique or you make a folder that you put the temp files in, and always cleanup after yourself so you don't bloat the temp folder.
Last edited by Rescator on Tue Aug 07, 2007 12:00 am, edited 1 time in total.
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Post by Joakim Christiansen »

Hehe, well, and here is how I did it for my prog:

Code: Select all

Procedure.s GetSpecialFolderPath(CSIDL.l)
  Protected *itemid.ITEMIDLIST, location.s = Space(#MAX_PATH)
  If SHGetSpecialFolderLocation_(0,CSIDL,@*itemid) = #NOERROR
    If SHGetPathFromIDList_(*itemid,@location)
      ProcedureReturn location
    EndIf
  EndIf
EndProcedure

Global AppdataPath$ = GetSpecialFolderPath(#CSIDL_APPDATA)
Global ProgramPath$ = GetPathPart(ProgramFilename())

If Not ProgramParameter(0) = "/portable" And FileSize("portable.txt") = -1
  If Not FileSize(AppdataPath$+"\JLC's Software")=-2
    CreateDirectory(AppdataPath$+"\JLC's Software")
  EndIf
  If Not FileSize(AppdataPath$+"\JLC's Software\Radio Player")=-2
    CreateDirectory(AppdataPath$+"\JLC's Software\Radio Player")
  EndIf
  SetCurrentDirectory(AppdataPath$+"\JLC's Software\Radio Player")
EndIf
And whenever is important for something to be saved in the same path as the executable use the ProgramPath$ variable. But for me, I didn't need to. Note how the user can easily change it into "portable" mode also.
I like logic, hence I dislike humans but love computers.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Joakim you got a memory leak,
please compare my SpecialFolderLocation() with your GetSpecialFolderPath()
PSDK/MSDN wrote:A pointer to an item identifier list (PIDL) specifying the folder's location relative to the root of the namespace (the desktop). The calling application is responsible for freeing this pointer
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Hi guys.

Thanks! Will look at these procedures in a few days. (Not being rude, just bogged down with the final stages of a business takeover and just about everything else is on the backburner at the moment).
Dare2 cut down to size
Post Reply