How should I store per-user data in WinForms? - winforms

In my WinForms app, I have a few textboxes that the user typed some data into. I want to store the data, but I don't want to use a database. In my stone-age C++ days, I'd just use a .ini. Somehow, app.config doesn't seem like the right place to store this data, though.
What are my other options?

I would say the .config file is the right place. Just be sure to use the User scoped area of the Settings.settings file rather than the Application scope.
This works well for simple data types and when you have fixed values that will need to be saved because you need to define what variables you want to store at design time. So if your textboxes are dynamically created and you don't know many values you need to store it is not very useful.
Using IsolatedStorage might be another good option. You can create your own file in any format you want (keeping any values you need) and store it to the local machine in "IsolatedStorage".

You can create a folder somewhere on the disk and simply write a file in any suitable format (XML, plain text, your choice). You could for instance do this under the path pointed out by Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).

I would look into isolated storage. It is easy to set up per-user. And since it requires only partial trust, it will work for any deployment scenario.
Check this introduction.

Depending on how many variables/data you're looking to save the app.config/settings file can be the ideal place.
Check out the Settings Tab in the Project properties and note that you can set both Application settings and User settings. Application settings affect the entire application. User settings are stored per user.
The section of the app.config that contains user settings will be saved to the user directory when they are saved and reincorporated when they restart the app.
Check this url for an introduction to Application/user settings on MSDN and also this SO url for a similiar question.:
You could also look into storing your familiar old .ini files in a per user .ini by checking out the Special Folders enum as per this url.

I believe the proper place to store user settings in WinForms 2.0 would be in the settings file (not the config file). Here's a quick article for explanation.

Create a .config or other data file (e.g. xml) in the application data for the specific user.
use system.environment.specialfolder to get the ApplicationData folder, add a subfolder with your company name, within this a subfolder with your application name, within this your data file for this specific user. Thus,
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YourCompany\\YourApplication\\YourData.config"

Related

VB.NET Copying Database template files to selected folder location during installation

net project as well as a setup project. I also have it so that during installation it asks the users to enter a file location to store their database. the plan is to have an empty .mdf file, with all the tables setup, copied into that folder and I store the folder path in a config file.
this is mainly because I am planning on having multiple separate applications that all need the ability to access the same database. I have it storing the folder path in my config file the only thing I'm having trouble with is
storing the template files I don't know if i should do this in the setup project or main project
how to copy said template files into a new folder
so far I have been unable to find a solution so any help is appreciated
Well here is what I do this in a few of my projects - something that has proven reliable enough for me over the years (which you may or may want to do as well):
I have the program itself create the database files in an initialization routine. First however, it creates the sub folders in which the database files will be stored, if they don't already exist.
To do this, the program just checks if the folder exists and if the database file exists and if they do not, it creates them on the spot:
If Directory.Exists(gSQLDatabasePathName) Then
Else
Directory.CreateDirectory(gSQLDatabasePathName)
End If
If File.Exists(gSQLiteFullDatabaseName) Then
Else
...
I also have the program do some other stuff in the initialization routine, like creating an encryption key to be used when storing / retrieving the data - but that may be more than you need (also, for full disclosure, this has some rare issues that I haven't been able to pin down).
Here too are some addition considerations:
I appreciate you have said that you want to give the user the choice of where to store their database files. However, I would suggest storing them in the standard locations
Where is the correct place to store my application specific data?
and only allowing the users to move them if the really need to (for example if the database needs to be shared over the network) as it will make the support of your app harder if every user has their data stored in different places.
I have found letting the user see in their options/settings windows where their database is stored is a good idea.
Also to encourage them to back those files /directories up.
Also to create automatic backups of several generations for the user.
Hope this helps.

Read content of folder without AIR in AS3 (no flash.filesystem)

I'm working on a project and I need to dynamically check what is in onhe of my folder. The idea is that I have the id of a quest, and there is a folder name after that id. My code needs to check if this folder exist AND if there is something in it. After that, it show all the picture inside that folder. The goal is that I will just have to add picture in a folder to have them appear in my game.
I tried to find a way to check the content of my folder, but everyone say that I need flash.filesystem, BUT it means that I need to use AIR. AIR does NOT work in FireFox or any other browser.
Here is the website that make me understood that:
http://www.experts-exchange.com/Software/Photos_Graphics/Web_Graphics/Macromedia_Flash/Q_26118847.html
How can I explore the content of my folders then?
There is absolutely no way to explore the local file system without user interaction in Flash. If you want to do it, you must make an AIR application, which is not browser-based. This is a security feature that is imposed by each browser (you can't do it in JS either) and implemented identically by Adobe.
You can use FileReference to allow a user to select file(s) for Flash to have access to or save a file, but that is the most interaction with the filesystem that will be possible without opening AIR (which is also not limitless. Even with AIR, you won't have full access to the file system and will be locked out of certain directories and prevented from doing certain things)
If the folders are on your server you'll need to rely on a server side script to do the job and pass the result to your app.
If you mean folders on client side computer it's not gonna be possible for security reason.

Image path in database vs intelligent folder structure

Assuming I want to safe one profile picture for each user of my system.
Is it better to save the path to this image in my database or to rely on a intelligent folder structure like
/images/users/user1.png
and access the image directly?
What if I have more then one picture per user? Would this be a good practice?
/images/user1/pic1.png
So basically my question is, why would you save the picture's path and waste space when you already know where the pictures are without any db queries?
This is just a general question apart from any technologies.
It's always better to assume that each user will have more than one picture, even if you're absolutely sure of otherwise now.. Two ways to go about it:
Each user will have a folder for all their pictures. /path/user1/img1.jpg , /path/user1/im2.gif
All the pictures will be in the same folder, but the username will be a prefix of the filename /path/user_pics/user1_img1.jpg , /path/user_pics/user2_img3.gif
Personally, I prefer the former.
In most cases, you won't need to store the full path of the picture in a database.. Storing the image content-type (which determines its extension) and the filename will generally be enough. That gives you more freedom as to which machine is serving the image itself.

Environment.SpecialFolderPath vs .NET Settings (& resolving environment variables in textbox binding)

I'm a C# noob, and I've been looking for info on best practices for C# application development.
I want to have an application setting that defines where the application will write its log files & reporting output. I want this to default to %USERPROFILE%\Documents\<Vendor>\<Tool>, since these files are created for the user to actually look at and dispose of at their leisure. But, if the user wants the files to be written to some other location, I want to persist their preferences.
My research so far indicates that:
It's not generally a good idea to use environment variables directly. Instead, it's recommended to use the Environment.GetFolderPath method and the Environment.SpecialFolders enum to get access to special locations in Windows like the user profile.
But, it's recommended to use user-scope .NET Application Settings to persist settings from one session to another.
Is there any good way to reconcile best practice 1 and best practice 2? Is it actually possible to store this default location in the Application Settings in a compatible way without referencing the %USERPROFILE% environment variable?
A related question:
Assume I keep %USERPROFILE%\Documents\<vendor>\<tool> as the default value for the Setting. I want the Setting's value to be bound to a textbox on the main application form (with a Browse button to select a new path). How can I bind the Setting to a textbox in such a way that %USERPROFILE% is resolved to a conventional filesystem path (eg C:\Users\<username>\Documents\<vendor>\<tool>) for purposes of display to the user?
I think that storing paths with environment variables is actually the best way to reference a special folder as a string and still make the path easily editable by the user, should s/he decide to do so.
Environment variables can be resolved to a simple string in .NET by calling the Environment.ExpandEnvironmentVariables method. You can use this method just before presenting the path in your TextBox and thus make it easily editable for the user. Once the user customizes the path, you can store it as an absolute path from there on, I suppose.

App.Config vs Custom XML file

I have read a lot of statements like "you shouldn't clog your app.config file with custom settings". However, I was under the impression that this was exactly the purpose of the file?
Is it just indeed a preference thing? Or are there any real benefits (other than separation of settings) by using a custom XML file, as apposed to the app.config file? If you need to explicitly separate settings would it better to use a custom ConfigurationSection rather than opting for a custom XML file?
I would like to here other peoples thoughts on this.
Some people tend to go a bit overboard on custom config section handlers, in my humble opinion.
I tend to use them only when I need something that is very structed; and that is used/written by 3rd parties (i.e. I want to do some extravagent validation on it).
I think you can quite happily use app.config/web.config for all relevant settings, and use separate XML files when it is very clear that is a separate component of the app.
Have a look at the Application Settings Architecture, the app.config is for Configration regarding the Application, thats quite a general term though.. So I would suggest you look into the Application Settings Files.
I would not store settings like "load database on startup or not" in the app.config. I would rather use an Alternative Storage like Application Settings for this, don't confuse Application Configuration with Settings, even though you might want to do that, Don't. app.config is supposed to have configration regarding lower level things like Database connection, Membership Provider or any other Application Critic information.
Most settings tend to fall into one of three camps:
Technical settings that affect the internal behaviour of the code, e.g. database connection string, data file path, logging switches, error handling switches, etc.
Business settings that affect the business logic of the product, e.g. "are users allowed to access the CRM Module?"
User-specific profile values, e.g. "is this user allowed to access the CRM Module?".
The natural place for type 1 is in app.config or web.config, and the natural place for types 2 and 3 is in the database.
App.Config are good for configuration that are application specific : path to database is a good example. The rest should be out of it.
One thing you might want to do is to create user-specific files, you can then use custom xml that will be saved into an IsolatedStore.
In my opinion I consider app.config to be good for deployment-time settings such as the location of the database, or an IP address or location of critical data file, etc. User settings like font, color, behavior preferences should go in a different file which you can easily create and save with Xml serialization.

Resources