Colen
Colen

Reputation: 13898

Where should my win32 program keep its files?

Our win32 applications (written in C++) have been around for over 10 years, and haven't been updated to follow "good practices" in terms of where they keep files. The application defaults to installing in the "C:\AppName" folder, and keeps application-generated files, configuration files, downloaded files, and saved user documents in subfolders of that folder.

Presumably, it's "best practices" to default to installing under "c:\Program Files\AppName" nowadays. But if we do that, where should we keep the rest of our files? Starting from Vista, writing to the program files folder is problematic, and there seem to be a million other places that you can put different files, and I'm confused.

Is there a reference somewhere for what goes where?


Edit: To expand on questions people have asked so far:


I'm familiar with the SHGetFolderPath function, but there are lots and lots of options that you can get from it, and I can't find a resource that says "Here is exactly what each of these options is used for, and when you might want to use it".

Up until now, we've done the "All files, including saved user files, under one folder" thing, and it's worked fine - but not when people want to install the app under the Program Files folder. For some reason, the virtualization monkeying around that Vista does isn't working for our application; if we're going to be making changes anyway, we might as well make an effort to do things the "right" way, since we don't want to have to change it again in 12 months time.


Further question:


We include some "sample" documents with our app, which we update every now and again. Is it appropriate to install them into My Documents, if we'll be overwriting them every few months? Or is My Documents assumed to be totally safe for users to mess around in?

If we can't install them to My Documents, where should we put them so that users can see them easily?

Upvotes: 12

Views: 3629

Answers (8)

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

Presumably, it's "best practices" to default to installing under "c:\Program Files\AppName"

Close, but not quite. Users can configure the name of the Program Files folder and may not even have a C: drive. Instead, install to the %ProgramFiles%\AppName environment variable folder.

Note you should assume you only have read access to this folder after the installation has finished. For program data files where you might need write access, use %AppData%\AppName.

Finally, are you sure yours is the only app with that name? If you're not 100% certain of that, you might want to include your company name in there as well.

The mechanisms you use to retrieve those variables will vary depending on your programming platform. It normally comes down to the SHGetFolderPath() Win32 method in the end, but different platforms like Java or .Net may provide simpler abstractions as well.

Upvotes: 17

mghie
mghie

Reputation: 32334

Use the Windows SHGetFolderPath() function to get the correct directories.

Edit: To reply to your other question, added in the edit: Where to put the sample files of your application does very much depend on whether your application is installed for a single user or for all users, and whether the person installing the application can be assumed to be the one who uses it.

If your program is to be used by multiple users on a system, copying stuff into "My Documents" is not going to work - the files would be accessible only for the user installing the application. Worse, if the only user of your application needed to install as Administrator, then [s]he will not have access to the files either. So unless you are fairly certain that there is only one user for your application, and they have sufficient permissions to install the application using their own account, don't use "My Documents".

IMO you should install sample files into the directory identified by CSIDL_COMMON_APPDATA. This will give you exactly one copy for all users, and since you want every user to see the original, unaltered sample files all users should consider them read-only. In fact, your setup program should probably make them read-only. Opening one of the samples will work for all users, but as soon as they try to save their modifications the application should detect that the file is read-only, and open the "Save As" dialog, pointing to "My Documents" or suitable directory inside. That will also keep all user modifications when the installer updates the sample files later on.

It is of course somewhat more difficult for the users to find the sample files. You could add a link to the samples folder to the start menu group of your application, so that access to the files is fast, and of course you should properly document everything.

Upvotes: 6

sebastus
sebastus

Reputation: 360

There is a directory structure under c:\users for user oriented data.

There is documentation for porting apps from older windows OSs to Vista.

Check out http://www.innovateon.com and follow the links to Vista. There is documentation regarding certification that has the details on topics like this.

Upvotes: -1

Paul Dixon
Paul Dixon

Reputation: 300825

Some guidelines are in this Knowledge Base article: How to write a Windows XP Application that stores user and application data in the correct location by using Visual C++. Also, if you search MSDN for Windows Logo Program you will find documentation regarding what an app needs to do to be truly compliant.

SHGetKnownFolderPath can get you the directories you need. If backwards compatibility with XP and earlier is required, use the deprecated SHGetFolderPath

Having said that, if you app came with documentation that said "everything used by this app is in this directory" I would love it ;)

Upvotes: 9

VolkA
VolkA

Reputation: 36681

For your application binaries, you can assume that you may write to the PROGRAM FILES directory (use the %ProgramFiles% environment variable to support installations other than the default English version - e.g. in german Installations this will be c:\Programme by default). Wikipedia lists the most common variables. Another option are the SHGetFolderPath or newer SHGetKnownFolderPath functions.

For User data, you should assume that the application is running with limited access rights and may only write to the user's home directory. Same applies for registry entries. This path should probably be configurable b the user, as the home directory may actually be a network server and a user might have a second disk attached for data storage. For information on the current (Vista) filesystem guidelines see this article.

Regarding plugins, this might be more complicated. The best practice seams to be offering the option to install for the current user only, and placing the plugin in the user directory, or install for all users and place the files into your program files directory (but remember to check for write permission and request elavated access if needed).

Upvotes: 2

Jiri
Jiri

Reputation: 16625

There are plenty of environment variables like: %USERPROFILE%, %HOMEPATH%, %APPDATA% all of these points to some user-specific directories, where you can put your user-specific files.

For system-wide storage you can use %ALLUSERSPROFILE%, that is the place where you should put your read/write datafiles that are not specific to any user.

Upvotes: 1

Michael Kristofik
Michael Kristofik

Reputation: 35178

Sorry I don't know the correct answer, but...

Do you have a business case for wanting to do that? Are your customers complaining that files aren't stored where they expect? Are your applications crippled in some way because you store files in non-standard locations? If not, I don't see a reason for spending time and budget to redo your file storage strategy just to meet "best" practice. If your programs just work, then IMHO you should leave them alone and spend money and time on things that matter.

Upvotes: -1

Beep beep
Beep beep

Reputation: 19141

We have a similar app created ~10 years ago using MFC. The easiest thing to do was create a folder right off of C:\ (e.g. C:\OurApp). No install files, no special permissions, no registry changes, etc. Clients (and particularly their sys admins) LOVE it.

One other consideration - are you planning to all of a sudden change the installation folder for existing clients (assuming this is installed in many locations)? If something isn't broke, why fix it?

Upvotes: -2

Related Questions