46

I'm developing a small C# Winforms game and one of the things I'm wanting to do is save application specific data. However, I'm struggling a bit to understand the correct place this should be stored.

As far as I can see there are several types of data an application might store and accordingly different places for it to be held:

1. Application properties - Settings such as where the application stores it's data, who the last logged in user was, the default window size, position etc. Is this information suppose to go into app.settings, or perhaps into the registry?

2. Global application data - This might include sprites and other game assets that are used by every user that runs the application on this machine. Where would this common data be stored? It's worth noting that in my particular case this data will not be provided with a default install and users will be allowed to add their own game assets which should be then available to any other user on the same computer.

3. User specific application data - This would include a users saved game files, their specific application preferences and their profile information. Where should I be storing this?

Ideally I wish my application to be compatible with Windows XP, Vista, 7 and of course the upcoming Windows 8 - I don't know if this changes the methods but hopefully it will assist with providing advice.

This is my first foray into this kind of development and I would appreciate some 'best practice' advice.

Martin
  • 39,569
  • 20
  • 99
  • 130

2 Answers2

42

Question 2:
I suggest using a subfolder in Environment.SpecialFolder.CommonAppData (maps to C:\ProgramData on Windows7 by default). This is a hidden folder.

Question 3:
Put those files into Environment.SpecialFolder.AppData(maps to C:\Users\[USERNAME]\AppData\Roaming by default, hidden folder), if you expect that the user does not intend to backup / modify those. Some games also put their save games into Environment.SpecialFolder.MyDocuments, probably because it is easier for users to find them there.

Example code:

var directory = Environment.GetFolderPath(Environment.SpecialFolder.AppData);


using (FileStream fs = File.Create(Path.Combine(directory, "myAppDirectory", "myFile.txt")))
{
    // write data               
}

For a complete list of special folders on Windows follow the link

SIDENOTES

yas4891
  • 4,774
  • 3
  • 34
  • 55
  • Some good advice. I edited my question to indicate that the files in question 2 may in fact be dynamic. – Martin May 12 '12 at 11:17
  • If you put something in the Documents folder you have to allow the user to click on it and launch the game with the right savegame loaded. Pretty much all games don't allow this so keep it in the appdata folder. – ZippyV May 12 '12 at 11:21
  • @ZippyV I don't see that as a valid reason to put your files into AppData. There are thousands of files on any system that can not be opened with a double click and that are not in AppData (or any hidden folder for that matter). The important reason here is whether you want your average user to be able to find the files. If so, `MyDocuments` it is. If not, store them in `AppData` – yas4891 May 12 '12 at 11:28
  • @yas4891 This all makes sense thanks - just one quick question. When using CommonAppData do I have to (check for the existence of and) create this directory myself or will the OS create it when I try to use it? – Martin May 12 '12 at 11:31
  • @yas4891 You don't want to clutter the Documents folder with files that are not documents and the user cannot use them unless they launch the game. – ZippyV May 12 '12 at 11:35
  • 1
    @Martin that folder should always be there. I've never experienced otherwise. But since you want to place your files into subfolder withhin `CommonAppData` you need to create a folder one way or the other (use `Directory.CreateDirectory()` for this). And while you're creating that (sub-)directory, you should definitely handle exceptions. – yas4891 May 12 '12 at 11:35
  • 1
    put a third bracket after "using (FileStream fs = File.Create(Path.Combine(directory, "myAppDirectory", "myFile.txt"))" just saying :) – Mohammad Mahroz Aug 30 '17 at 19:04
7

Application properties - Most application data you described should be specific to each user and put in Environment.SpecialFolder.ApplicationData (the %appdata% environment variable). I would generally avoid putting data in the registry as it is hard to find, edit, and fix. If you do not want data to be associated with the user when they are roaming (maybe the files are big or connected to the computer in someway) then you can put it in Environement.SpecialFolder.LocalApplicationData (the `%localappdata% environment variable).

Global application data - I would put global application data in Environment.SpecialFolder.CommonApplicationData ( the %programdata% environment variable)

User specific application data - Same as #1, except when the data is intended to be easily found by the user (e.g. saved games) in which case it should go in Environment.SpecialFolder.MyDocuments, which has no associated environment variable.

As yas4891 points out you can reliably get these folder paths using Environment.GetFolderPath() using one of the Environment.SpecialFolder` values listed here.

cdiggins
  • 17,602
  • 7
  • 105
  • 102