【问题标题】:Where to store program settings instead of HKEY_LOCAL_MACHINE?在哪里存储程序设置而不是 HKEY_LOCAL_MACHINE?
【发布时间】:2010-09-22 01:35:21
【问题描述】:

我有一些当前存储在 HKEY_LOCAL_MACHINE 中的程序设置。由于 Vista 和锁定的用户,一些用户没有 HKEY_LOCAL_MACHINE 的权限,而且这些值也不真正属于 HKEY_LOCAL_USER(它必须对所有用户都相同),存储这些的最佳替代位置是什么?

大部分设置已经存储在数据库中,但在连接到数据库之前程序需要了解一些设置。理想情况下,我会喜欢一种无需检查正在运行的操作系统即可实现此功能的方法。

这是一个用 Delphi 编写的桌面应用程序。

【问题讨论】:

  • 这将是来自 Vista 的一件好事,即使没有其他好处。在最终清除所有这些垃圾之后,我们将拥有更干净的注册表。
  • 您确定他们没有读取权限吗? XP 上的标准用户也没有 HKLM 的读写权限。
  • 我想我可以澄清更多。它们也是用户写入注册表的设置。
  • 作为标准用户,您的应用程序在 Windows 2000 或 Windows XP 下的表现如何?这将指导您作为标准用户在 Windows Vista 或 Windows 7 下的行为方式。

标签: delphi registry


【解决方案1】:

你应该输入:

  • 注册表中HKEY_CURRENT_USER 下或CSIDL_APPDATA 或CSIDL_LOCAL_APPDATA 文件夹中的个人设置(如窗口位置和次要首选项);
  • 注册表或应用程序文件夹中HKEY_LOCAL_MACHINE 下的重要应用程序设置(如用​​户不应修改的固定路径)。在安装时设置它们,当管理员权限可用时;
  • CSIDL_COMMON_APPDATA 文件夹中的共享数据(您的所有用户都应该读写的数据,例如简单的数据库)。

使用SHGetFolderPath 查找CSIDL_* 文件夹的位置。

根据您的需要,您可能希望同时实现所有三个选项。不会有问题的。

【讨论】:

    【解决方案2】:

    可能是在注册表中放置它们的好地方,我不知道,但为什么不直接在 C:\Documents and Settings\All Users\Application Data\yourApp 中添加一个 ini 文件

    【讨论】:

    • 当然,从编程环境中获取该路径,而不是对 C: 驱动器进行硬编码。
    • 当然,它甚至在环境中:APPDATA
    【解决方案3】:

    @uli 所说的,除了一个例外。

    永不更改或仅应由管理员更改的设置可以--应该甚至-- 保存在与应用程序相同的文件夹中,以帮助防止篡改。

    数据库的连接信息听起来像是在没有管理员干预的情况下不应该更改的东西。因此,在这种情况下,您的应用程序文件夹可能没问题。

    【讨论】:

      【解决方案4】:

      您提到了 HKEY_LOCAL_USER,但我在注册表的顶层没有看到它。我猜你一定是指 HKEY_CURRENT_USER。

      我将我的用户设置放在 HKEY_CURRENT_USER/Software/my-program 下。我发现这在 Vista 下运行没有问题。

      但既然你说你有适用于所有用户的设置,你不希望在 HKEY_CURRENT_USER 下,那么你可以尝试:

      HKEY_USERS/.DEFAULT/Software/your-program

      或

      HKEY_CURRENT_CONFIG/软件/你的程序

      恐怕我不使用这些位置中的任何一个,所以我无法告诉您它们是否可以在 Vista 上运行,但我确实看到一些软件供应商已经在那里添加了注册表项。

      【讨论】:

      • HKEY_USERS/.DEFAULT 不是一个好主意。这实际上是新用户 HKEY_CURRENT_USER 的模板。这是放置默认值的好地方。每当在机器上创建新用户时,其 HKCU 密钥将从 HKEY_USERS/.DEFAULT 开始填充
      【解决方案5】:

      将内容保存在 %APPDATA% 或 %LOCALAPPDATA% 中

      【讨论】:

        【解决方案6】:

        问问自己您的设置是否真的适用于所有用户。 真的适用于所有用户吗?

        仔细思考这个问题:

        软件如何在 Windows XP 下作为标准用户运行?

        • 软件只是崩溃了吗?
        • 是否禁用了配置选项?
        • 您是否告诉您的客户他们必须以管理员身份运行,如果他们拒绝了,您就不会支持它?

        因为如果您的软件绝对需要您是管理员,那么只需将清单添加到可执行文件中,说明它需要以管理员身份运行:

        <?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>
        

        然后,您是管理员。


        但我不认为你真的需要成为管理员。您需要本地计算机设置的唯一情况是,如果您要让来自多个登录或会话的用户使用该软件。如果真的是适用于每个用户的东西,安装程序不应该设置它吗?

        我们在这里提出了同样的问题。监控系统需要配置软件将使用哪个捕获设备。您可以说所有监视操作员都将使用相同的捕获设备,因此一旦选择它,该设置对所有操作员都是全局的。但这在实践中是不正确的。可能只有一次捕获设备,而且它是我们使用的那个。如果有多个设备,则用户只需选择另一台设备即可。


        但是有几种方法可以解决这个问题

        i) 将设置保存在注册表中,并让安装程序在密钥上设置 ACL,让所有用户完全控制。

        ii) 将设置保存在

        %APPDATA%\Surveillance\settings.ini

        文件。让安装程序创建设置文件,并对其进行 ACL 以允许所有用户拥有完全控制

        iii) 将设置存储在上述注册表项或 ini 文件中,然后使用

        将 UAC Shield 添加到您的保存/确定/应用按钮。当用户按下按钮时,您重新启动提升的应用程序(使用RunAsAdmin),并传递指示您要更改的命令行参数。

        iv) 与 3 相同,但在他们进入用于编辑值的屏幕之前执行此操作。

        v) 与 4 相同,但最初的值是只读的,如果他们想更改它们,就必须提升它们。

        vi) 如果用户作为标准用户运行,并且如果他们想要更改它们,请禁用这些选项:右键单击可执行文件并选择

        以管理员身份运行


        如果这是一个用户可以随时更改的选项(当您在 Windows XP 上运行并且用户是管理员时),那么用户可以随意编辑该值似乎是可以接受的。

        在这种情况下,您可以让用户输入服务器的名称,就像他们之前允许的那样。如果用户有权写入 HKLM,则将选项保存在那里。否则将其保存在 HKCU 中。读取要使用的服务器时,从 HKCU 开始,如果 HKCU 值不存在,则移动到 HKLM。

        【讨论】:

          【解决方案7】:

          重新使用 ini 文件 - 注意项目似乎有 2048 byte 限制。

          因此,我陷入了困境 - 编码的许可证信息徘徊在(当时未知的)限制附近,并且当它们超过时似乎总是“神秘地”打破......

          【讨论】:

          • 那是因为 TIniFile 的 Delphi 内部实现使用 2kB 的常量缓冲区来调用 GetPrivateProfileString... 所以你会被卡住。要克服这个问题,请使用 TMemIniFile 类。
          【解决方案8】:

          您能否制作一个 .msi 文件,用于通过组策略将注册表设置推送出去?

          【讨论】:

          • 不适用于在 Vista 上运行的消费者应用程序。
          • 具有数据库的消费者应用程序需要记录其连接详细信息?
          • 是的。但他也询问了更一般的情况,即一般意义上的正确位置在哪里。
          【解决方案9】:

          总是有老式的 INI 文件。它们比注册表设置更便携。另一种选择是 XML 文件。

          不要将它们存储在 Program Files 目录中 - Vista 不会喜欢这样。

          【讨论】:

            【解决方案10】:

            我在这里阅读了所有答案以及其他地方的内容,答案似乎是......不要使用注册表!这真的是微软希望我们对适用于所有用户的程序配置数据做的事情吗!?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-03-13
              • 1970-01-01
              • 2014-09-21
              • 1970-01-01
              • 2013-06-19
              • 2011-10-12
              • 1970-01-01
              相关资源
              最近更新 更多