Application settings methods? c++ - c++

I am thinking about adding configurable settings to an application, and I think the easiest ways are an external file or win registry (its a win only app).
Which way would be better?
I was wondering, an user with not enough permissions may not be able to create/write the config file. And in the case of the registry, would todays antivirus allow me to add/edit/remove keys? Or they only monitor certain keys?
Also, if someone knows a class/lib to manage config settings (in pure win32) in vc++ please post it.

As far as I know:
an user with not enough permissions may not be able to create/write the config file
You should be able to make files inside user's "home directory" or "application data" directory, regardless of permissions. Normally those directories should be writeable.
would todays antivirus allow me to add/edit/remove keys?
Haven't ever seen my antivirus interfere with registry manipulation. You probably will be fine as long as you aren't doing anything suspicious in registry.
Which way would be better?
It is matter of taste. I think that text file is better - allows easier migration of settings. Just don't leave junk behind after uninstall.
Also, if someone knows a class/lib to manage config settings in vc++
QSettings in Qt 4. But using entire Qt for just saving settings is definitely an overkill. You could also check configuration languages like JSON, use lua for settings (less overkill than using Qt 4) or get any XML library. Also, working with registry directly or writing configuration files using iostreams or stdio shouldn't be hard. And you can always write your own configuration library - if you feel like it.

Is "Windows-only" a restriction or a restriction-relief? If you don't mind being cross-platform then I suggest you give boost::program_options a go. The library supports program options through commandline, through evironment-variables and through INI files. Boost's program_options also integrates and glues the various parsers very nicely with variables_map, which you can view as a map between options and their value.

For simple stuff, you might as well just use the registry. However, there are many benefits to a config file... you can save/load several different configs for different uses of your app, it's easier to share or migrate settings between users or machines, etc.
If you end up going the file route, I would recommend Boost's Property Tree library:
http://www.boost.org/doc/libs/1_41_0/doc/html/property_tree.html
It has a pretty nice syntax:
boost::property_tree::ptree properties;
std::string name = properties.get<std::string>("blah.name");
int score = properties.get<int>("blah.score");
properties.put("blah.name", "Inverse");
properties.put("blah.score", 1000);
It also supports reading and writing to various formats, like xml and others.

I think the new default thing is to write a configuration file in the user's "AppData" folder under the user's folder which should be safe to write/read from.
We're using a simple XML formatted file to store settings; but you could use a INI file type formatting.

If you save your configuration file in the Application Data directory SHGetFolderPath() with CSIDL_COMMON_APPDATA all users will be able to see the configuration. If you use CSIDL_LOCAL_APPDATA then only the one user will be able to see the configuration. The registry is not necessarily the place to save all configuration data.

Related

Where can I put my SQLite database in my QT application if I can't put it in my resources?

Recently I was trying to put a SQLite database into a QT 5 application I'm writing. I want it to be universally accessible - that is on all systems regardless of where it's installed. I put it as a resource then found out that evidently you can't put databases in resources as the string for the database path passed to setDatabaseName doesn't get translated to the resource system so the database can't be found.
So where can I put it? I don't want to just put it at the root of the drive like C:\repo.db or D:\repo.db as many people hate files cluttering their root directories (like me). I was going to put it just in the source folder and access it as "repo.db" or as I tried "./resources/database/repo.db" but even QFile doesn't see that. Where can I put it and how to access it there? My settings file was going to be in my resources but I wasn't sure if I could update the file then. I need a place that is available from the moment the application is installed on any system including my own so that it can be accessed both while coding it and when it's built.
I'm not asking for opinions - I want a place that is not in the root, somewhere universal like the installation directory (but how do I find that with code?) or a settings directory (but how do I set that somewhere so I can find it later??)
For such purposes Qt provides a list of QStandardPaths functions that return platform specific standard paths, such as a path to desktop, temp directory etc.
For your particular case you might put your database in the directory that corresponds to the QStandardPaths::AppDataLocation key.
You can use QSettings to save path,settings and restore them.
QSettings m_Arhive("Company", "app_name");
//Set DB path
m_Arhive.setValue("DBPath", "c:/somewhere/database");
//Get DB path
m_Arhive.value("DBPath").toString()

log4cplus - how do I change the log file name at runtime?

I'd like to have several related programs use the same log4cplus configuration file but each write to a different filename. That way the log files go into the same place, are the same size and use the same internal format (etc).
log4cplus::PropertyConfigurator doesn't expose the "find this option and change it" methods that I suspect might work, and I'm reluctant to play with the source code until I'm sure there's no other way.
In log4j that's easy using system properties and there's an extension to make it even easier, but I can't see how to do the same in log4cplus.
I'm using NetBeans/G++ 4.7.3/C++11/Ubuntu if that's helpful to know.

How to create extended (custom) file property in Windows?

We have a proprietary file format which has embedded in it a product-code.
I am just starting down the path of "enabling the end-user to sort / filter by product-code when opening a file".
The simplest approach for us might be to simply have another drop-down in our customized Open File Dialog in which to choose a product-code to filter by.
However, I think it might be more useful to the end-user if we could present this information as a column in the details view for this file type - just as name, date-modified, type, size, etc., are also detail properties of a file-type (or perhaps generic to all files).
My vague understanding is that XP and prior Windows OSes embedded some sort of meta data like this in an alternate data stream in NTFS. However, Starting in Vista Microsoft stopped using alternate data streams due to their dependence upon NTFS, and hence fragility (i.e. can't send via file attachment, can't move to a FAT formatted thumb drive, etc.)
Things I need to know but haven't figured out yet:
Is it possible / Is it practicable / how to create a custom extended file property for our file type that expresses the product-code to the Windows shell so that it can be seen in Windows Explorer (and hence File dialogs)?
If that is doable, then how to configure things so that the product-code column is displayed by default for folders containing our file type.
Can anyone point me to a good starting point on the above? We certainly don't have to accomplish this by publishing a custom extended file property - but that seems like a sensible approach, in absence of any way to measure the costs of going this route.
If you have sensible alternative approaches to the problem, I'd be interested in those as well!
Just found: http://www.codeproject.com/Articles/830/The-Complete-Idiot-s-Guide-to-Writing-Shell-Extens
CRAP! It seems I'm very late to the banquet, and MS has already removed this functionality from their shell: http://xpwasmyidea.blogspot.com/2009/10/evil-conspiracy-behind-customizable.html
By far the easiest approach to developing a shell extension is to use a library made for the purpose.
I can recommend EZShellExtension because I have used it in the past to add columns and thumbnails/preview for a custom file format for our company.

The Best way of storing/retrieving config data in Modern Windows

I've not done much coding for Windows lately, and I find myself sitting at Visual Studio right now, making a small program for Windows 7 in C++. I need some configuration data to be read/written.
In the old days, (being a Borland kind of guy) I'd just use a TIniFile and keep the .ini beside my exe Obviously this is just not the done thing any more. The MS docs tell me that Get/WritePrivateProfileString are for compatibility only, and I doubt that I'd get away with writing to Program Files these days. Gosh I feel old.
I'd like the resulting file to be easily editable - open in notepad sort of thing, and easily findable. This is a small app, I don't want to have to write a setup screen when I can just edit the config file.
So, what is the modern way of doing this?
Often people use XML files for storing preferences, but they are often overkill (and they aren't actually all that readable for humans).
If your needs would be easily satisfied with an INI file, you may want to use Boost.Program_options using the configuration file parser backend, which actually writes INI-like files without going through deprecated (and slow!) APIs, while exposing a nice C++ interface.
The key thing to get right is where to write such configuration file. The right place is usually a subdirectory (named e.g. as your application) of the user's application data directory; please, please, please, don't harcode its path in your executable, I've seen enough broken apps failing to understand that the user profile may not be in c:\Documents and settings\Username.
Instead, you can retrieve the application data path using the SHGetFolderPath function with CSIDL_APPDATA (or SHGetKnownFolderPath with FOLDERID_RoamingAppData if you don't mind to lose the compatibility with pre-Vista Windows versions, or even just expanding the %APPDATA% environment variable).
In this way, each user will be able to store its preferences and you won't get any security-related errors when writing your preferences.
This is my opinion (which I think most of the answers you get will be opinion), but it seems that the standard way of doing things these days is to store config files like these in C:\Users\<Username>. Moreover, it is generally good to not clutter this directory itself, but to use a subdirectory for the purpose of storing your application's data, such as C:\Users\<Username>\AppData\Roaming\<YourApplicationName>. It might be overkill for a single config file, but that will give you the opportunity to have all of your application data in one place, should you add even more.

Shared configuration file format between python and C?

I'm looking to implement a shared configuration file that will be written (output) in python, but be read (input) in C.
The only prerequisite of this configuration file is that it can't be human readable.
Anyone have any suggestions on what file format I should use for this project?
Edit: The file can't be human readable because we don't want the user to be able to modify the configuration, also, in some cases, we don't want the user to know about certain configurations.
How secure do you need this config file to be?
There is no absolute security, you'll quickly run into DRM like issues (allow users to open a file but not allow them to open it ... I know it's insane).
Often simple obfuscation is quite effective. Dump the config to a JSON file (please don't use xml). XOR the contents and change the extension. That will stop all casual inspection of the file. Obviously don't document that this is your obfuscation procedure.
If you're worried about user modification of config files (you don't care if the configs are readable you just want prevent loading custom configs) use a cryptographic signature. Store the private key at your company and use it and the python app to generate a signed configuration. Store the public key in the c++ application and use it to verify the config is properly signed before applying the settings.
try this one http://www.picklingtools.com/
Probably easiest to use XML, then obfuscate it with a simple cypher or encryption with a fixed key.
Use a plain human readable format such as XML, and then obfuscate that to make it uneditable (i.e. encrypt the whole thing and store a hash somewhere and fail to load if its' been messed with).
Otherwise you just have to bite the bullet and write a spec for the binary format that'll be exchanged between the two programs.