Friday, July 4, 2014

Choose the Right Folder for Your Application Data

I'm in the process of updating an older program that will now use a local database. I followed my typical "old school" habits and quietly went about my way thinking "I'll just plop the database in a folder called Data that resides in the same location as the exe file. No big deal."

I figured, I'll just use the reliable ExtractFilePath(Application.ExeName) to get the location of where this Data folder needs to go. Right?


I had forgotten to think about how Delphi's "debug" and "release" paths will play into this scenario. Not to mention 32Bit and 64Bit targets. I'm only focused on creating a Windows product at the moment, so for me this means there are a minimum of five paths:


I know I could use "Post-Build" commands (Project > Options > Build Events) to make sure the files are copied from the $(PROJECTDIR) to the $(OUTPUTDIR). However, I was thinking that this is not a very efficient way to go about it. Did I really want to have five copies of a 140MB database cluttering up my hard drive. The answer is no.

So I posed the question "Looking for best practice for using single-user local database." to the Delphi Community on Google+ (

I received several comments and the consensus was to use an application specific subfolder of CommonAppData. Fair enough. CommonAppData it is. What the heck is CommonAppData?

I tend to be a "Show Me" guy I decided to dive into this head long and found out that CommonAppData actually refers to the folder called C:\ProgramData.

Then I wondered what all the other "AppData" type folders were. So I wrote a simple little program to help figure this out. It turns out there are 17 different AppData folders on my computer. I've included a copy of my program for you to use.

AppData Only: Sorted by Path Column

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Paths'
  ClientHeight = 411
  ClientWidth = 804
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnResize = FormResize
  OnShow = FormShow
  DesignSize = (
  PixelsPerInch = 96
  TextHeight = 13
  object StringGrid1: TStringGrid
    Left = 16
    Top = 39
    Width = 772
    Height = 354
    Anchors = [akLeft, akTop, akRight, akBottom]
    ColCount = 3
    FixedCols = 0
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goFixedRowClick]
    ParentFont = False
    TabOrder = 0
    OnFixedCellClick = StringGrid1FixedCellClick
  object Button1: TButton
    Left = 16
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Close'
    TabOrder = 1
    OnClick = Button1Click
  object Button2: TButton
    Left = 97
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Get Folders'
    TabOrder = 2
    OnClick = Button2Click
  object CheckBox1: TCheckBox
    Left = 184
    Top = 12
    Width = 97
    Height = 17
    Caption = 'AppData Only'
    TabOrder = 3
    OnClick = Button2Click


Enjoy - Semper Fi,
Gunny Mike


  1. Very nice!

    Possible further development (feel free to ignore :) ):

    * Option to see the current setting and the default setting?

    * Expand to show all CSIDL values (see: ?

    * Expand to include SHGetKnownFolderPath ( and it known folders ( ? I know that is one is a bit different but I think it would be handy also.

  2. Alternatively you may also create a symbolic link of your Data folder to your Release and Debug folders, so that the Data folder can still be made relative to your executable even while debugging :)

    1. @Chee Meng - I've never heard of symbolic references. Whaere can I learn more? Please don't "let me google that for you". I'd rather you sent me to specific references you feel are worthy. :-)

    2. Sorry Riley, I did not get notification for reply earlier.

      Symbolic links have been used for a long time in *nix systems, to avoid data duplication… and also for easier version control of executables/shared libraries. For instance you may have a and a, and a symbolic link called that currently points to That way, new compilations will refer to that will always point to the latest file, while at the same time you may still directly reference older versions if you want to. And when you get a new file, say,, you then point to the latest file and again, future compilations will use the latest file. In *nix and OSX you may achieve that with the “ln -s” command.

      In Windows, you may use the mklink command from the command prompt, or the CreateSymbolicLink[Transacted] API calls.

      Wikipedia is still a good source of reference and perhaps even this quick premiere