Page 1 of 1

Preferences file handling on fixed/removable drives

Posted: Sat Jan 12, 2008 3:08 pm
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

Posted: Sat Jan 19, 2008 11:21 am
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?

Posted: Mon Jan 21, 2008 3:25 pm
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.

Posted: Mon Jan 21, 2008 4:54 pm
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?)

Posted: Mon Jan 21, 2008 10:19 pm
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.

Posted: Mon Jan 21, 2008 11:57 pm
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. :)

Posted: Tue Jan 22, 2008 11:36 am
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.