Standard location of system-wide configuration files of an app? - windows-vista

Since Windows Vista, our friends from Redmond are putting an end to the habit of storing configuration files in C:\Program Files\<AppName>\config.ini. Ok, they introduced Registry Virtualisation, but it's always better to fix your stuff, right?
I'm planning to fix a pre-Vista app which runs as a service, and which needs to maintain a machine-wide configuration file.
Where do I store the config file? And what would be the most portable/future-proof way of obtaining the path to that location?

You could store the values in the registry in something inheriting from \HKLM\ directly, which would give portability.
If there are a large number of values, or a complex structure to them, then you could store a file location in the registry, and store your configuration at that destination.

After improving my Google-fu starting from a related question, I think I've found the definitive answer in this microsoft blog post which actually describes much more than what I originally wanted to know.

Related

Trying to create a script to change settings on Plantronics hub

I’m new to the IT industry but keen to learn.
Wanted to ask if anyone could point me in the right direction when trying to create a Powershell script to change settings within a computer app called plantronics hub.
Just need a better insight to what commands I need to use and functions. Just so that instead of going to a users machine every time and changing the settings I can just run a script and let it do it for me.
There are a few things you can look at. Look through the program files to see if there's any kind of command line utility for this sort of thing. Obviously, documentation is another good place to look. If available, you can also call their support and simply ask. Keep in mind they may have already considered this scenario, and may have other suggestions.
Try and figure out how the application stores its settings, Registry, XML, ini file etc...? PowerShell can work with any of these, but you need to answer this question before knowing what direction to go it.
If the settings are in the registry I'd start looking under HKLM:/ & HKCU:\Software\Plantronics. Settings and/or configuration files may be in the program files folder or under the user profile app data folders.
A few techniques:
Export the registry, make a configuration change, export the registry again to a different file. Compare the 2 files via some file comparison tool, like BeyondCompare or WinMerge. This might help you find anything that changed after you made the change.
Use procmon.exe . If you filter it properly you can determine which files the application is touching either on start or when you make a configuration change. ProcMon can also help identify which registry keys and values are being looked at.
Note: If the settings are consistent between stations you may be able to copy the config. This could be as simple as a file copy or importing a registry file.

How to detect OneDrive online-only files

Starting from Windows 10 Fall Creators Update (version 16299.15) and OneDrive build 17.3.7064.1005 the On-Demand Files are available for users (https://support.office.com/en-us/article/learn-about-onedrive-files-on-demand-0e6860d3-d9f3-4971-b321-7092438fb38e)
Any OneDrive file now can have one of the following type: online-only, locally available, and always available.
Using WinAPI how can I know that the file (e.g. "C:\Users\Username\OneDrive\Getting started with OneDrive.pdf") is online-only file?
After years, I'm still using FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS attribute described here to determine if a file or a directory is completely present locally or not.
Microsoft docs says the following for FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS:
When this attribute is set, it means that the file or directory is not fully present locally. For a file that means that not all of its data is on local storage (e.g. it may be sparse with some data still in remote storage). For a directory it means that some of the directory contents are being virtualized from another location. Reading the file / enumerating the directory will be more expensive than normal, e.g. it will cause at least some of the file/directory content to be fetched from a remote store. Only kernel-mode callers can set this bit.
There are some advantages of FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS:
It can be used for both files and directories.
It can be set in kernel mode only, so there is no chance for anyone to set the attribute arbitrary.
And as it described in this answer, there are still some interesting undocumented attributes which can provide additional information about cloud files.
Note: I didn't accept Jonathan Potter's answer because I mentioned FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS attribute in comments and started using it a year earlier than he updated his answer.
To check for "online only" all you need is to call GetFileAttributes() and see if the FILE_ATTRIBUTE_OFFLINE attribute is set.
In fact this isn't new for OneDrive, that attribute has existed for a long time.
There are other OneDrive attributes available via the shell (although the property you need is PKEY_StorageProviderState rather than PKEY_FilePlaceholderStatus) but "online only" is easy to check for.
Edit: Another filesystem attribute, FILE_ATTRIBUTE_PINNED is new for Windows 10, and is used by OneDrive to indicate a file that's "always available".
Edit: As of 2019 it appears that OneDrive now uses FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS rather than FILE_ATTRIBUTE_OFFLINE, as suggested below.
Edit: PKEY_StorageProviderState was broken in Windows 10 1903, and still not fixed in 1909. It returns 4 ("uploading") for all files in any apps other than Explorer.
Take a look at the PKEY_FilePlaceholderStatus property for the file (at the shell level, not the file-system level). This blog post has a example program you can test. This question also hints to some undocumented properties you might want to take a look at.
Microsoft has a UWP example on MSDN.

Associate Windows directory with program (or treat directory as file)

This is likely not a simple topic - I have researched this to the best of my abilities and realize that it is not supported in any typical fashion.
My goal is to enable something similar to .app files from OSX, where the application, as well as its user data, can exist in the same file. I imagine it would require writing a tool to manage this behaviour, but this question is more about how to achieve this in the Windows OS. I am quite flexible regarding the implementation details, but the more straightforward the behaviour, the better (i.e. avoiding copying or compressing/decompressing entire directories/archives at runtime would be ideal).
Approaches I have considered:
Find a way to get explorer to treat a directory as a file, so that it can be associated. I have found a way to get explorer to treat a directory as a control panel item, I have thus far been unable to find a way to use this to associate a custom program. See the infamous "godmode hack" for Windows (name a directory something to the effect of "GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}"). This one seems the most hopeful, but I'm at wits end trying to find information about creating a new association of this type.
Come up with some kind of archive format which can extract executable information to a temporary directory, launch this executable passing the archive as a commandline parameter. This seems like the ugliest solution, from a performance perspective. I would prefer a different solution if at all possible, one which doesn't involve making duplicates of the program or its data to run.
Find a way to associate a directory directly, though I have found no trace of this being supported in Windows, and I assume this is a dead-end.
Find a way to get an executable to include writeable embedded files. I have been unable to make any headway with this- I even tried a resource hacker approach, but obviously you cannot modify the assembly while its in use.
Tried to make a self-modifying JAR file with Java, but the route I took would add the JDK as a runtime requirement, which seems a bit overkill. Even then, it would be limited to Java, and I'm pretty sure it's not actually supposed to allow that in the first place.
Modify Windows Explorer. I shudder at the amount of work this would take, not to mention the at-best gray area it falls under legally. Perhaps there's a way to extend explorer to achieve this, I'm not sure.
A custom archive file. This seems like the most straightforward way to do it. But it would ideally need to be an archive format that has very little overhead for file I/O. Could even be some kind of virtual disk that gets mounted, but I am imagining that would be pretty heavy.
I would appreciate any insight that anyone has on this topic. I won't go into reasons as they are irrelevant to the question itself- I'm aware it is likely not the most practical solution to anything in particular. Consider it a novel pursuit.
It can be done by application virtualization,
Read this wikipedia page theory:
https://en.wikipedia.org/wiki/Portable_application
https://en.wikipedia.org/wiki/Application_virtualization
And two pages about software:
https://en.wikipedia.org/wiki/VMware_ThinApp
https://en.wikipedia.org/wiki/Turbo_(software)
Windows 7 added the ability for a Desktop.ini file to add/change the folder verbs on a per-folder basis. Using that trick it is possible to create a "folders as applications" style setup.

Q: Neo4j-wrapper.conf. Can I put more information into the Wrapper configuration files?

I'm working on updating the Neo4j windows installation process into Powershell and I was thinking that perhaps it could read/write neo4j windows service information from the neo4j-wrapper.conf configuration file.
The Windows wrapper conf has very little information that is related the windows service itself (in fact I think it has no information that is used in the creation, management and removal process!)
My intention is to have the relevant windows service information in the configuration file and then when calls such as Install or Stop are made, then the Service Name can be retrieved from there instead of via command line arguments.
My questions are;
If I put more information into that configuration file, will it affect the linux wrapper?
Is there any reason why I shouldn't put more settings into the configuration file (but only related to a Windows Service)?
Note - My changes would also support this PR;
https://github.com/neo4j/neo4j/pull/4433
Thanks,
Glenn.
I think the answer is, in principle, yes. Putting extra stuff in that file wouldn't hurt anything.
But it's not ideal to have a single file that's used for different purposes on different platforms (I see the presence there of Linux-specific service stuff as a problem rather than something to copied).
The real solution, I think, is for each package build to provide its own copy of that file (or one derived from a common starting point).

Registry vs. INI file for storing user configurable application settings [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm a new Windows programmer and I'm not sure where I should store user configurable application settings. I understand the need to provide a user friendly means for the user to change application settings, like an Edit | Settings form or similar. But where should I store the values after the user hits the Apply button on that form?
What are the pros and cons of storing settings in the Windows registry vs. storing them in a local INI file or config file or similar?
Pros of config file:
Easy to do. Don't need to know any Windows API calls. You just need to know the file I/O interface of your programming language.
Portable. If you port your application to another OS, you don't need to change your settings format.
User-editable. The user can edit the config file outside of the program executing.
Pros of registry:
Secure. The user can't accidentally delete the config file or corrupt the data unless he/she knows about regedit. And then the user is just asking for trouble.
I'm no expert Windows programmer, but I'm sure that using the registry makes it easier to do other Windows-specific things (user-specific settings, network administration stuff like group policy, or whatever else).
If you just need a simple way to store config information, I would recommend a config file, using INI or XML as the format. I suggest using the registry only if there is something specific you want to get out of using the registry.
Jeff Atwood has a great article about Windows' registry and why is better to use .INI files instead.
My life would be a heck of a lot easier if per-application settings were stored in a place I could easily see them, manipulate them, and back them up. Like, say... in INI files.
The registry is a single point of failure. That's why every single registry editing tip you'll ever find starts with a big fat screaming disclaimer about how you can break your computer with regedit.
The registry is opaque and binary. As much as I dislike the angle bracket tax, at least XML config files are reasonably human-readable, and they allow as many comments as you see fit.
The registry has to be in sync with the filesystem. Delete an application without "uninstalling" it and you're left with stale registry cruft. Or if an app has a poorly written uninstaller. The filesystem is no longer the statement of record-- it has to be kept in sync with the registry somehow. It's a total violation of the DRY principle.
The registry is monolithic. Let's say you wanted to move an application to a different path on your machine, or even to a different machine altogether. Good luck extracting the relevant settings for that one particular application from the giant registry tarball. A given application typically has dozens of settings strewn all over the registry.
There's one more advantage to using an INI file over the registry which I haven't seen mentioned:
If the user is using some sort of volume/file based encryption, they can get the INI file to be encrypted pretty easily. With the registry it will probably be more problematic.
According to the documentation for GetPrivateProfileString, you should use the registry for storing initialisation information.
However, in so saying, if you still want to use .ini files, and use the standard profile APIs (GetPrivateProfileString, WritePrivateProfileString, and the like) for accessing them, they provide built-in ways to automatically provide "virtual .ini files" backed by the registry. Win-win!
There's a similar question here that covers some of the pros and cons.
I would suggest not using the registry unless your application absolutely needs it. From my understanding, Microsoft is trying to discourage the use of the registry due to the flexibility of settings files. Also, I wouldn't recommend using .ini files, but instead using some of the built-in functionality to .Net for saving user/app settings.
Use of an ini file, in the same directory as the application, makes it possible to back it up with the application. So after you reload your OS, you simply restore the application directory, and you have your configuration the way you want it.
I agree with Daniel. If it's a large application I think I'd do things in the registry. If it's a small application and you want to have aspects of it user-configurable without making a configuration form, go for a quick INI file.
I usually do the parsing like this (if the format in the .ini file is option = value, 1 per line, comments starting with #):
static void Parse()
{
StreamReader tr = new StreamReader("config.ini");
string line;
Dictionary<string, string> config = new Dictionary<string, string>();
while ((line = tr.ReadLine()) != null)
{
// Allow for comments and empty lines.
if (line == "" || line.StartsWith("#"))
continue;
string[] kvPair = line.Split('=');
// Format must be option = value.
if (kvPair.Length != 2)
continue;
// If the option already exists, it's overwritten.
config[kvPair[0].Trim()] = kvPair[1].Trim();
}
}
Edit: Sorry, I thought you had specified the language. The implementation above is in C#.
As Daniel indicated, storing configuration data in the registry gives you the option to use Admin Templates. That is, you can define an Admin Template, use it in a Group Policy and administer the configuration of your application network-wide. Depending on the nature of the application, this can be a big boon.
The existing answers cover a lot of ground but I thought I would mention one other point.
I use the registry to store system-wide settings. That is, when 2 or more programs need the exact same setting. In other words, a setting shared by several programs.
In all other cases I use a local config file that sits either in the same path as the executable or one level down (in a Configuration directory). The reasons are already covered in other answers (portable, can be edited with a text editor etc).
Why put system-wide settings into the registry? Well, I found that if a setting is shared but you use local config files you end up duplicating settings. This may mean you end up needing to change a setting in multiple places.
For example, say Program A and Program B both point to the same database. You can have a "system-wide" registry setting for the connection string. If you want to point to a different database, you can change the connection string in one place, and both programs will now run against the other database.
Note - there is no point in using the registry in this way if two or more programs don't need to use the same values. Such as, Program A and Program B both needing a database connection string that may be the same, but not always. For example, I want Program B to now use a test database but Program A should carry on using a production database.
With the above example, you could have some local configuration override system-wide settings but it may start getting overly complicated for simple tasks.
The registry is optimized for quick access and easy update, and it's the only way to do certain Windows-specific things like associating with an extension. And you can ignore the argument about deleting a single directory to uninstall your program - Windows Vista won't let you modify files in the Program Files directory, so your config will need to go in a different folder anyway.
There's a general guideline for Windows programming - do things the way Microsoft expects you to, and your life will be a lot easier.
That said, I can see the appeal of the INI file, and I wouldn't blame anyone for considering it.
There is one drawback to ini or config files and that is locating them if the user has the option to select where the program is installed.
Other disadvantage of using the registry is that it is a pain if you are working in a mixed environment of 32 and 64 bit applications, as the system call for accessing the registry will randomly(*) add \Wow6432Node\ to your registry path making you crazy while debugging.
(*of course not randomly, but very easy to get lost)
Advantages:
Replacement for a large number of configuration files.
Common administrative functions at a central point.
Almost any data can be saved by applications / drivers.
In contrast to configuration files, code sequences can even be saved.
Access faster than files because the database is indexed.
Access can be logged using the RegMon utility
Disadvantages:
Difficult to work with in the absence of graphical configuration programs.
Direct changes using the registry editor can create inconsistent states produce.
Incomplete uninstallers leave “reminiscences” in the registry Cause problems, e.g. with a new installation.
Installed applications are difficult to export to other PCs.
Chronically poorly documented.
Proprietary structure, therefore not suitable for standard DB access (e.g. SQL)
Computer-specific, therefore not portable to other computers.
Insufficient protection of the registry: depends on the configuration.

Resources