App.config vs. .ini files - c#

I'm reviewing a .NET project, and I came across some pretty heavy usage of .ini files for configuration. I would much prefer to use app.config files instead, but before I jump in and make an issue out of this with the devs, I wonder if there are any valid reasons to favor .ini files over app.config?

Well, on average, .INI files are probably more compact and in a way more readable to humans. XML is a bit of a pain to read, and its quite verbose.
However, app.config of course is the standard .NET configuration mechanism that is supported in .NET and has lots of hooks and ways to do things. If you go with .INI files, you're basically "rolling your own all the way". Classic case of "reinventing the wheel".
Then again: is there any chance this is a project that started its life before .NET ? Or a port of an existing pre-.NET Windows app where .INI files were the way to go?
There's nothing inherently wrong with .INI files I think - they're just not really suported in .NET anymore, and you're on your own for extending them, handling them etc. And it certainly is a "stumper" if you ever need to bring outside help on board - hardly any .NET developer will have been exposed to .INI files while the .NET config system is fairly widely known and understood.

Ini files are quite okay in my book. The problem is GetPrivateProfileString() and cousins. Appcompat has turned that into one ugly mutt of an API function. Retrieving a single ini value takes about 50 milliseconds, that's a mountain of time on a modern PC.
But the biggest problem is that you can't control the encoding of the INI file. Windows will always use the system code page to interpret strings. Which is only okay as long as your program doesn't travel far from your desk. If it does, it has a serious risk of producing gibberish when you don't restrict the character set used in your INI file to ASCII.
XML doesn't have this problem, it is well supported by the .NET framework. Whether by using settings or managing your config yourself.

Personally I never user .ini /xml config files to anything more than loading all the values into a singleton or something and then use them runtime like this...
That being said i firmly believe that you should look at the kind of data and the use of data. If the data is in the context of the application in terms of settings and comfigurations then i believe that the app.config file is the right place to hold these settings.
If on the other hand the data is concerned about loading projects, images or other resources concerned with the content of the application then i believe the .ini (does anyone use .ini files anymore? I am thinking a .xml file for storing these information). In short: Segment the content of the data being stored according to the domain and the context.

INI files are preferable for multi-platform applications (e.g., Linux & Windows), where the customer may occasionally edit the configuration parameters directly, and where you want a more user-friendly/-recognizable file name without the extra effort.

Related

Best practice for WPF application user settings storage?

I'm refactoring a WPF application and dealing with cleaning up storage of settings. I've re-written most to use the application's settings (Properties.Settings.Default) and this technically is working right now it seems to generate rather ugly paths in the %appdata% folder such as:
C:\Users\me\AppData\Local\Company_Name_With_Underscores\program.exe_Url_xs3vufrvyvfeg4xv01dvlt54k5g2xzfr\3.0.1.0\
These also then result in a new version number folder for each version that don't get cleaned up ever unless apparently I manually do so via file io functions.
Other programs don't seem to follow this format, including Microsoft programs, so I'm under the impression this seems like one of those 'technically the best way but not practical so nobody uses' solutions. Is this the case or am I missing something to make this more practical?
I ask mainly because I can foresee issues if we ever have to direct a customer to one of these folders to check or send us a file from there.
I'm using .NET 4.0 right now.

The best approach for file backup using .NET

There are number of possible solutions to do file backup application. I need to know which method would be rock-solid and professional way to perform copying of data files even though the file is being used or very large sized.
There is a known method called Volume shadow copy (VSS), however I've read that it is an overkill for a simple copying operation and instead the PInvoke BackupRead can be used.
.NET framework provides it's own methods:
File.Copy was (and possibly still is) problematic with large files and sharing the resources
FileStream seems to be suitable for backup purposes however I didn't locate comprehensive description and I am not sure if I'm correct.
Could you please enlighten me which method should be used (maybe I have overlooked some options) and why? If the VSS or PInvoke methods are preferred could you please also provide an example how to use it or some reference to comprehensive documentation (particularly I'm interested in the correct settings to create file handle, which would allow sharing the resources when the file is in use).
Thanks in advance.
Everything you're going to try in a live (i.e. currently running OS) volume will suffer from not being able to open some files. The reason is, applications and the OS itself opens files exclusively - that is, they open the files with ShareMode=0. You won't be able to read those files.
VSS negotiates with VSS-aware applications to release their open files for the duration, but relatively few applications outside Microsoft are VSS aware.
An alternative approach is to boot to another OS (on a USB stick or another on-disk volume) and do your work from there. For example, you could use the Microsoft Preinstallation environment (WinPE). You can, with some effort run a .Net 4.x application from there. From such an environment, you can get to pretty much any file on the target volume without sharing violations.
WinPE runs as local administrator. As such, you need to assert privileges, such as SE_BACKUP_NAME, SE_RESTORE_NAME, SE_SECURITY_NAME, SE_TAKE_OWNERSHIP_NAME, and you need to open the files with a flag called BACKUP_SEMANTCS...as described here.
The BackupRead/BackupWrite APIs are effective, if awkward. You can't use asynchronous file handles with these APIs...or at least MS claims you're in for "subtle errors" if you do. If those APIs are overkill, you can just use FileStreams.
There are bunches of little gotchas either way. For example, you should know when there are hardlinks in play or you'll be backing up redundant data...and when you restore, you don't want to break those links. There are APIs for getting all the hard links for a given file...NtQueryInformationFile, for example.
ReparsePoints (Junctions and SymLinks) require special handling, too...as they are low-level redirects to other file locations. You can run in circles following these reparse points if you're not careful, and even find yourself inadvertently backing up off-volume data.
Not easy to deal with all this stuff, but if thoroughness is an issue, you'll encounter them all before you're done.

How to provide a huge amount of files as a part of your application

So, my application depends on a huge number of small files. The actual number is somewhere around 90,000. Now, I use a component that needs an access to these files, but the only way it accepts them is by the use of an URI.
So far I have simply added a directory containing all the files to my debug-folder while I have developed the application. However, now I have to consider the deployment. What are my options on including all these files with my deployment?
So far I have come up with a couple of different solutions, none of which I've managed to make work completely. First was to simply add all the files to the installer which would then copy them to their places. This would, in theory at least, work, but it'd make maintaining the installer (a standard MSI-installer generated with VS) an absolute hell.
The next option I came up with was to zip them into a single file and add this as a part of the installer and then unzip them by the use of a custom action. The standard libraries, however, do not seem to support complex zip-files, making this a rather hard option.
Finally, I realized that I could create a separate project and add all the files as resources in that project. What I don't know is how do the URIs pointing to resources stored in other assemblies work. Meaning, is it "standard" for everything to support the "application://,,,:Assembly"-format?
So, are these the only options I have, or are there some other ones as well? And what would be the best option to go about this?
I would use a single zip-like archive file, and not unzip that file on your hard disk but leave it as is. This is also the approach used by several well known applications that depend on lots of smaller files.
Windows supports using zip files as virtual folders (as of XP), users can see and edit their content with standard tools like Windows Explorer.
C# also has excellent support for zip files, if you're not happy with the built in tools I recommend one of the major Zip libraries out there - they're very easy to use.
In case you worry about performance, caching files in memory is a simple exercise. If your use case actually requires the files to exist on disk, also not an issue, just unzip them on first use - it's just a few lines of code.
In short, just use a zip archive and a good library and you won't run into any trouble.
In any case, I would not embed this huge amount of files in your application directly. Data files are to be separate.
You could include the files in a zip archive, and have the application itself unzip them on first launch as part of a final configuration, if it's not practical to do that from the installer. This isn't entirely atypical (e.g. it seems like most Microsoft apps do a post-install config on first run).
Depending on how the resources are used, you could could have a service that provides them on demand from a store of some kind and caches them, rather than dumping them somewhere. This may or may not make sense depending on what these resources are for, e.g. if they're UI elements a delay on first access might not be acceptable.
You could even serve them using http from a local or non-local server, or a SQL server if it's already using one, caching them as well, which would be great for maintenance, but may not work for the environment.
I wouldn't do anything that involves an embedded resource for each file individually, that would be hell to maintain.
Another option could be to create a self-extract zip/rar archive and extract it from the installer.
One of the options is to keep them in compound storage and access them right in the storage. The article on our site describes various types of storages and their advantages / specifics.

Is it a bad practice to store config data in the registry?

I'm currently working on a Winforms app created by someone else. I've noticed that all the configurations are stored in the registy. This includes connection strings and so on.
Is this good or bad practice? If bad, then what is the better alternative?
A better option for you and the user is to use configuration files stored in the per-user application data directories. Look at the documentation for the System.Configuration namespace. Version 2.0 of the framework added a lot of functionality beyond the per-application config files.
I think a better option would be to store them in an app.config. This gives better visability and frankly is easier to change.
If you want to hide your app settings, most users aren't savvy enough to go hunting through the registry for keys relevant to an application. Also, as other answers have pointed out, back in the days before XML configuration file standards, the registry was the recommended place.
The recommended option is an XML config file nowadays; it won't add data to a file that's loaded at startup, meaning you're not contributing quite as much to the problem of a computer with a lot on it getting an inflated registry. It's more easily changeable (provided your user has admin access, and in any case, your program will need special permission to access the file to make programmatic changes).
If you kind of want to keep the data away from the casual user, a SQLite database is a relatively lightweight way to store small amounts of data, like user settings, in a manner that isn't easily changeable without access to SQLite. Just remember that if you can get in, so can others, no matter how hard that may be.
It's mostly an old practice from pre .NET days (VB6 comes to mind), when there were no standard configuration files and Microsoft recommended storing configuration in the registry.
These days, the registry is a good place to store information that is used by several applications, but if this is not the case, you should prefer the application configuration file.

Get the path to the current application settings file

I have so many bloody different nested folders with different names that were all automatically created by the settings engine that I can no longer tell where the active settings file resides on my machine. Is there a way to determine the path to the active settings file programmatically so I can output it to a debug console?
It isn't often that I can post the exact same answer within 2 minutes. Copy-and-paste:
I'm going to be a bit blunt about this. The .NET framework design is overall rather excellent. Easy to learn, few surprises, no fat. But not everything is great. System.Configuration has a very high suck factor. Between an absurdly complicated object model and an implementation that was paralyzed by security concerns, it inevitably becomes a PITA when you try to extend it beyond the point-and-click settings designer.
Just don't go there. Using XML serialization to load/save your own configuration class(es) is a wholeheckofalot easier than battling that borked design.

Categories