Preferences file handling on fixed/removable drives

Share your advanced PureBasic knowledge/code with the community.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Preferences file handling on fixed/removable drives

Post by utopiomania »

This code stores preferences files in the application folder if the application is on a
removable drive, if not it stores the preferences file in the users profile folder.

This way, if the program is installed, users aren't stuck with each others settings and
the preferences file location isn't virtualised under Vista. If it isn't installed, just
carried around on a removable drive, the program doesn't write anything to the host
computer.

Code: Select all

; Uses the application folder to store preferences if the program
; is running from a removable drive. If running from anything else
; it stores the preferences files in the user profile folder

declare writePreferences(inFolder.s, name.s)
declare readPreferences(inFolder.s, name.s)
declare.s getSpecialFolder(id)


;demo code
global location.s

writePreferences("Preferences File Test", "Preferences File Test.prefs")
readPreferences("Preferences File Test", "Preferences File Test.prefs")

messageRequester("Preference File", "Written to: " + location)
runProgram(getPathPart(location))

end
;end demo code


procedure writePreferences(inFolder.s, name.s)
  #CSIDL_APPDATA = $1A
  ;	XP:     C:\Documents and Settings\username\Application Data*    
  ;	Vista:  C:\Users\username\AppData\Roaming
  if len(inFolder)
    inFolder + "\"
  endIf
  path.s = getPathPart(programFileName())
  type = getDriveType_(left(path, 2))
  if type = 2
    ;removable
    path = path + inFolder
  else
    path = getSpecialFolder(#CSIDL_APPDATA) + inFolder
  endIf
  createDirectory(path)
  if createPreferences(path + name)
    ; insert your own preferences code below
    preferenceGroup("location")
      writePreferenceString("is", path + name)
    ; insert your own preferences code above
    closePreferences()
    procedureReturn 1    
  endIf
  procedureReturn 0
endProcedure

procedure readPreferences(inFolder.s, name.s)
  #CSIDL_APPDATA = $1A
  ;	XP:     C:\Documents and Settings\username\Application Data*    
  ;	Vista:  C:\Users\username\AppData\Roaming
  if len(inFolder)
    inFolder + "\"
  endIf
  path.s = getPathPart(programFileName())
  type = getDriveType_(left(path, 2))
  if type = 2
    ;removable
    path = path + inFolder + name
  else
    path = getSpecialFolder(#CSIDL_APPDATA) + inFolder + name
  endIf
  openPreferences(path)
    ; insert your own preferences code below
    preferenceGroup("location")
    location = readPreferenceString("is", "unknown")
    ; insert your own preferences code above
  closePreferences()
endProcedure

procedure.s getSpecialFolder(id)
  shGetSpecialFolderLocation_(0, id, @pidl) 
  path.s = space(#MAX_PATH) 
  shGetPathFromIDList_(pidl, @path)
  if right(path, 1) <> "\"
    path + "\"
  endIf
  if pidl 
   coTaskMemFree_(pidl)
  endIf 
  procedureReturn path
endProcedure
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

Nice man, thanks for sharing. I was going to write something similar today.

It's something that many programmers overlook but nonetheless is a very important matter indeed. One should always respect the user, and also avoid them any unnecessary trouble while providing them with a smooth platform to work with/at.

I will, however, modify your routines a little to suit my specific needs (if you don't mind)
:)

Fred: any chance of upgrading the preference lib with something similar to this?, it's not gibberish to add such functionality; after all, it's a high-level library.

utopiomania: what about media such as CDROM?
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Hi, glad you can use it :)
utopiomania: what about media such as CDROM?
In this case getDriveType.. should return DRIVE_CDROM (=5) and the function will write
the preferences file to the users profile folder.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Really nice. Thank You :)

(I was under the impression that things in users profile folder are always virtualised....isn't it? maybe not in cases like this?)
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

and the function will write the preferences file to the users profile folder.
I just burnt a program to a CD-R to to confirm this, and it saves its preferences in the users profile folder (thank you, Bill!).

@SFSxOI, what I mean by virtualisation in this context is the way Vista 'virtualises' the program files folder so that if an
app tries to write something in its own application folder there, the write is silently redirected to the users virtual store
(if he's not an admin). This is for backward compatibility, but it's not recommended as I understand MS.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

utopiomania wrote:
and the function will write the preferences file to the users profile folder.
I just burnt a program to a CD-R to to confirm this, and it saves its preferences in the users profile folder (thank you, Bill!).

@SFSxOI, what I mean by virtualisation in this context is the way Vista 'virtualises' the program files folder so that if an
app tries to write something in its own application folder there, the write is silently redirected to the users virtual store
(if he's not an admin). This is for backward compatibility, but it's not recommended as I understand MS.
ahhhhh...OK I see what your talking about now. Thanks for explaining that for me. :)
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

And thanks for sharing ;)

I'm still working on my little preferences lib, takes time to get it just right. I want to mix xml and the preferences lib of pb into one helper lib so I can more easily manage this kind of stuff.

Thing is, I want to do it in an abstract way so the day of tomorrow I can swap any of the libs easily.
Post Reply