问题
I have some program settings that are currently stored in HKEY_LOCAL_MACHINE. Due to Vista and locked down users, some users don't have permission to HKEY_LOCAL_MACHINE, and those values don't really belong to HKEY_LOCAL_USER either (it has to be the same for all users), what's the best alternative location for storing these?
Majority of settings are stored in the DB already, but there are some that the program needs to know about before connecting to the DB. Ideally I'll like a way to implement this without needing to check what operating system is running.
This is for a desktop app written in Delphi.
回答1:
You should put:
- personal settings (like window position and minor preferences) under
HKEY_CURRENT_USERin the registry or in theCSIDL_APPDATAorCSIDL_LOCAL_APPDATAfolder; - important application settings (like a fixed path that should not be modified by your users) under
HKEY_LOCAL_MACHINEin the registry or in the application's folder. Set them at install time, when administrator privileges are available; - shared data (data that all of your users should read and write to, like a simple database) in the
CSIDL_COMMON_APPDATAfolder.
Use SHGetFolderPath to find the location of the CSIDL_* folders.
Depending on your needs you might like to implement all three options given at once. There would be nothing wrong with it.
回答2:
Might be some good place in the registry to put them I don't know about, but why not just add an ini-file in C:\Documents and Settings\All Users\Application Data\yourApp
回答3:
What @uli said, with one exception.
Settings that never change or should only be changed by an administrator can --should, even-- be kept in the same folder as the application to help prevent tampering.
Connection info for a database sounds like the kind of thing that shouldn't be changed without administrator intervention. Therefore in this case your application's folder might be okay.
回答4:
You mentioned HKEY_LOCAL_USER, but I don't see that in the top-level in the Registry. I am guessing you must mean HKEY_CURRENT_USER.
I put my user settings under HKEY_CURRENT_USER/Software/my-program. I find that this works under Vista without problem.
But since you say you have settings that apply to all users that you don't want under HKEY_CURRENT_USER, then you might try either:
HKEY_USERS/.DEFAULT/Software/your-program
or
HKEY_CURRENT_CONFIG/Software/your-program
I'm afraid I don't use either of those locations so I can't tell you if they work on Vista or not, but I do see that some software vendors have added registry entries there.
回答5:
Save stuff in %APPDATA% or %LOCALAPPDATA%
回答6:
Ask yourself if your setting really is for all users. Is it really for all users?
Carefully think about this question:
How did the software run under Windows XP as standard user?
- Did the software simply crash?
- Was configuring the option disabled?
- Did you tell your customers that they had to run as an administrator, and if they refused then you wouldn't support it?
Because if your software absoutely requires you to be an administrator, then simply add the manifest to the executable saying it needs to be run as an administrator:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="IsUserAdmin"
type="win32"/>
<description>Description of your application</description>
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
And presto, you're an administrator.
But i don't think you really need to be an administrator. The only time you need a local machine setting is if you're going to have users from multiple logins or sessions using the software. If it really is something that applies to every user, shouldn't the installation program have set it up?
We had the same question come up here. A surveillance system needs to configure which capture device will be used by the software. You could say that all surveillance operators will be using the same capture device, so once one picks it, that setting is global to all operators. But that's just not true in practice. Chances are there's only once capture device, and it's the one we use. If there's more than one, then the user can simply pick another device.
But there are a few ways to handle this
i) Have the settings saved in the registry, and have the installation program set the ACL on the key give all users Full Control.
ii) Have the settings saved in the
%APPDATA%\Surveillance\settings.ini
file. Have the installation program create the settings file, and ACL it to allow all users to have Full Control
iii) Store the settings in a the above mentioned registry key or ini file, and use
- Button_SetElevationRequiredState Macro or the
- icon IDI_SHIELD
to add the UAC Shield to your Save/OK/Apply button. When the user pushes the button, you relaunch your app elevated (using RunAsAdmin), passing command line parameters indicating what you want to change.
iv) Do the same as 3, but do it before they can get into the screen that is used to edit the values.
v) Do the same as 4, but have the values initially read only, and if they want change them they have to elevate.
vi) Have the options disabled if the user is running as a standard user, and if they want to change them: right-click the executable and select
Run as administrator
If this is an option that a user was able to change whenever they liked (when you were running on Windows XP and the user was an administrator), then it seems that user's being able to edit the value at will is acceptable.
In this case you can just let the user type in the name of the server, as they were allowed to do before. If the user has permission to write to HKLM, then save the option there. Otherwise save it in HKCU. When reading which server to use, start with HKCU and move to HKLM if HKCU value is not there.
回答7:
Re using ini files - beware that there seems to be a 2048 byte limit on items.
I've come unstuck because of this - encoded licence info hovering around the (then unknown) limit & something that always seemed to work breaking 'mysteriously' when they go over...
回答8:
Can you make a .msi file that can be used to push the registry settings out through group policy?
回答9:
There's always old fashioned INI files. They are more portable that registry settings. Another option would be an XML file.
Don't store them in the Program Files directory though - Vista won't like that.
回答10:
I read all the answers here and stuff elsewhere and the answer seems to be... Don't use the registry! Is this really what Microsoft wants us to do with program config data that applies to all users!?
来源:https://stackoverflow.com/questions/285277/where-to-store-program-settings-instead-of-hkey-local-machine