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

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.

Related

How to track the number of times my console application in C++14 has been launched?

I'm building a barebones Notepad-styled project (console-based, does not have a GUI as of now) and I'd like to track, display (and later use it in some ways) the number of times the console application has been launched. I don't know if this helps, but I'm building my console application on Windows 10, but I'd like it to run on Windows 7+ as well as on Linux distros such as Ubuntu and the like.
I prefer not storing the details in a file and then subsequently reading from it to maintain count. Please suggest a way or any other resource that details how to do this.
I'd put a strikethrough on my quote above, but SO doesn't have it apparently.
Note that this is my first time building such a project so I may not be familiar with advanced stuff... So, when you're answering please try to explain as is required for a not-so-experienced software developer.
Thanks & Have a great one!
Edit: It seems that the general advice is to use text files to protect portability and to account for the fact that if down-the-line, I need to store some extra info, the text file will come in super handy. In light of this, I'll focus my efforts on the text file.
Thanks to all for keeping my efforts from de-railing!
I prefer not storing the details in a file
In the comments, you wrote that the reason is security and you consider using a file as "over-kill" in this case.
Security can be solved easily - just encrypt the file. You can use a library like this to get it done.
In addition, since you are writing and reading to/from the file only once each time the application is opened/closed, and the file should take only small number of bytes to store such data, I think it's the right, portable solution.
If you still don't want to use a file, you can use windows registry to store the data, but this solution is not portable

Can you embed files into exe, and update them with each use?

I'm trying to make an application which to manage information about several providers.
Target system is windows and I'll be coding with c++.
The users are not expected to be handy on anything related to computers, so I want to make it as fool-proof as possible. Right now my objective is to distribute only an executable, which should store all the information they introduce in there.
Each user stores information of their own providers, so I don't need the aplication to share the data with other instances. They do upload the information into a preexisting system via csv, but I can handle that easily.
I expect them to introduce new information at least once a month, so I need to update the information embedded. Is that even possible? Making a portable exe and update its information? So far the only portable apps I've seen which allow saving some personification do so by making you drag files along with your exe.
I try to avoid SQL to avoid compatibility problems (for my own applications I use external TXTs and parse the data), but if you people tell me it's the only way, I'll use sql.
I've seen several other questions about embedding files, but it seems all of them are constants. My files need to be updatable
Thanks in advance!
Edit: Thanks everyone for your comments. I've understood that what I want is not worth the problems it'd create. I'll store the data separatedly and make an effort so my coworkers understand what's the difference between an executable and it's data (just like explaining the internet to your grandma's grandma...)
While I wouldn't go as far as to say that it's impossible, it will definitely be neither simple nor pretty nor something anyone should ever recommend doing.
The basic problem is: While your .exe is running, the .exe file is mapped into memory and cannot be modified. Now, one thing you could do is have your .exe, when it's started, create a temporary copy of itself somewhere, start that one, tell the new process where the original image is located (e.g., via commandline arguments), and then have the original exit. That temporary copy could then modify the original image. To put data into your .exe, you can either use Resources, or manually modify the PE image, e.g., using a special section created inside the image to hold your data. You can also simply append arbitrary data at the end of an .exe file without corrupting it.
However, I would like to stress again that I do not recommend actually doing stuff like that. I would simply store data in separate files. If your users are familiar with Excel, then they should be familiar with the idea that data is stored in files…

How to write a shell extension in C++?

This seemed like a common question but after doing some searching, I wasn't really able to find my answers. There is an article on this here:
http://www.codeproject.com/KB/shell/shellextguide1.aspx
But it's for a very old version of Visual Studio. I'm using VS 2008, so the instructions and interfaces don't seem to match what I'm seeing.
I want to create a simple shell extension using C++ that creates a context menu for files with extension .GZ. When right clicking on these files, I should be able to click my context menu item and have a callback in code to do some sort of operation on that file.
Other context menu items would do things like spawn modless dialogs to accept user input before executing some action.
From what I've seen, ATL is used for this but I have never used ATL, so all of the object types and interfaces are very confusing to me. It wouldn't be so bad if I had a proper tutorial or documentation to read.
Can anyone help me out? Isn't there some sort of tutorial out there that isn't 10 years old?
I can't tell you exactly how to write a shell extension, but I will provide a number of tips. Writing a Shell Extension offers some significant advantages over the much simpler “registry-only” method:
With a Shell Extension, you can dynamically create a context menu item (or submenu) that is more relevant to the selected file(s). For example, if you are writing a Shell Extension for zip files, it is possible to create a submenu within the context menu that shows the entire contents of the zip.
You can handle multiple files simultaneously, which may be more beneficial not just for performance purposes but also so that you can work out what to do based on the selection as a whole rather than just for each file.
Some of the downfalls to Shell Extensions are:
Substantially increased complexity. Be prepared to spend a lot of effort on this to get it working. Have a home-espresso machine installed next to your computer and/or hire someone to make you coffee.
Substantially increased difficulty in debugging. Ditto about coffee.
It's difficult to write a Shell Extension because they can be very hard to debug.
Shell Extensions are loaded by the explorer.exe process, and without specific configuration of Explorer, you need to force-quit the explorer.exe process so that you can install a newer version of your Shell Extension. There is a way to get Explorer to unload DLLs that it is no longer using, but you should only do this on a development machine and not on a deployment target:
In RegEdit, browse to the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer
Add a new DWORD key called “AlwaysUnloadDLL” and set its value to 1.
Restart explorer.
This works most of the time, but there may still be times where you need to close Explorer because the Shell Extension was not unloaded.
Keep in mind that your Shell Extension may be loaded by other applications, for example, if you right-click on a file with an applications “open file” dialog, then your Shell Extension will be loaded into that application, and not Explorer.
If your Shell Extension causes a runtime error, quite often the result will simply be that your context menu item does not show, very rarely will you be told that your Shell Extension failed to load or that it caused a runtime error.
Configuration can be hard, even with an installation, registry data needs to be created in several places, and depending where you want your context menu to show, the places in the registry may differ between different versions of Windows.
What you'll need to do:
Visual Studio offers some shortcuts to creating Shell Extensions, but basically you'll need to create a COM DLL. A Shell Extension for context menu items must implement both the IContextMenu interface and the IShellExtInit interface.
In the IShellExtInit::Initialize() method, you can obtain the selected files from the IDataObject parameter. From memory, the data is in “Drag-n-Drop” format, so you need to get an HDROP handle from the IDataObject and query the files from there (this is from memory, it may actually be different than as I described here, so proceed with caution).
Once your DLL is ready to be “installed”, you must copy it somewhere, and then run regsvr32 to make sure it is registered.
Follow this guide to know where to put registry keys.
There may be issues with 64-bit Windows, if you build a 32-bit DLL it may not load in 64-bit Explorer… so keep this in mind if you are having trouble with 64-bit Windows.
Your DLL will actually have two GUIDs associated with it. I can't remember exactly how it works, but one GUID refers to the DLL itself and the other refers to the actual Shell Extension. Make sure you use the GUID of the actual Shell Extension when creating keys in the registry where a GUID is required.
All things considered… (tl;dr)
Weigh up the costs of whether a Shell Extension is worth it. If you want to create menu items dynamically based on the selected files, then a Shell Extension may be the only way. If you want to handle all files simultaneously then you'll probably need a Shell Extension as well.
An alternative to the context menu method, could be to have a drag-n-drop target on the user's desktop or something. Explore other ways that you could have the user submit your files to your application, because a Shell Extension is often far more effort than it is worth. I found this out the hard way and I think everyone else has too.

Application settings methods? 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.

How can I write my own 'filesystem' within Windows?

I've recalled using little 'filesystems' before that basically provided an interface to something else. For example, I believe there was a GMail filesystem that created an entry in My Computer and could be used like any other drive on your local computer. How can I go about implementing something like this in C++?
Thank you!
Try Dokan. It's like FUSE, except for Windows. I think there are certain limitations to namespace extensions, like they cannot be accessed from the command line, but I'm really not sure as of now.
Writing an actual file-system involves writing a driver; which means kernel-mode code (scary stuff) and paying for getting the IFS DDK. (edit: looks like they don't charge for it anymore)
What you probably want is a “namespace extension”.
Try this: The Complete Idiot's Guide to Writing Namespace Extensions - CodeProject
This may be a starting point to extending NTFS in the way that the GMail filesystem used to do: Windows NT reparse points.
The GMail Filesystem is just the name given; it is not any filesystem as such. It is just a namespace extension for Windows Explorer that links with the GMail account of yours!
I dont know exactly what you are trying to do, but in anyway, I believe, the following link will be of some use to you:
http://msdn.microsoft.com/en-us/magazine/cc188741.aspx
Just as a reference: virtual drives can be created using our Callback File System product, which is a supported, documented and maintained solution.
I was thinking of this too, perhaps some example code ? (email me if i forget plz ;p doin sdk now)
I'm thinking of a similar filesystem that would plug in as a driver and allow dynamic 'soft raid' on larger files mostly by putting them on more than one disk, perhaps some compression options and 'smart' filters to toggle usage in high disk space low usage and other situations more effectively, with status controls and indicators as a normalish program too
Seems like I would load the driver kit,
then i want the file writing event, and am mostly replacing fopen and similar functions automatically as an intermediate driver with a little windows network driver experience
I also heard good things about developing on a virtual machine for less crashing and more debugging
Also perhaps more metainfo on some or all files, including files in special folders with options too, including maybe both fast and simple (obfuscated and/or symmetic key) encryption options on folder, specified, all, letter, etc, or whatever, or the slower version and maybe integrated and optional (also profitable) online cvs-like diff style backups that mostly target changes to hot files for online backup at intervals and prices, mostly perhaps with matching keyboard events and might even be useful as simply a keylogging online backup service that is reasonably secure too
while avoiding common files like windows files or the normal stuff in the 'programs' directory that can be copied easily with pirate tools, unlike all of your documents.