【问题标题】:Editing/Modifying C# Application Settings编辑/修改 C# 应用程序设置
【发布时间】:2017-01-09 11:19:38
【问题描述】:

.NET 配置设置功能不像我希望的那样灵活。 如果我正确理解Application Settings,我将受限于何时可以更改/编辑设置。在 C# 中,应用程序设置分为两种不同的类型或范围(“应用程序”和“用户”),但在如何更改或修改它们方面都有限制。下表说明了不同之处:

范围:|设计时编辑:|运行时编辑:|会话之间的编辑: -------------------------------------------------- ------------------------------------- 用户 |设置.settings | Settings.Default.Save() | *不支持* 应用 |设置.settings | *不支持* |编辑 app.exe.config

是否有任何“内置”设置功能允许我通过所有三种机制编辑设置?使用配置文件的主要动机之一是允许用户在不重新构建源代码的情况下更改默认值(可以通过 Application-scoped 设置来完成)。但是,不应强制用户编辑 .config 文件;他们还应该能够在运行时进行跨设置持续的更改(可以通过 User-scoped 设置来完成)。肯定有某种机制可以同时提供这两种功能。

底线:为什么不能在运行时编辑应用程序设置 (app.exe.config)?那将解决我所有的问题。 我了解这可能会给共享同一台机器的用户带来问题。但是谁再这样做了?

可能的解决方法:是否可以将用户设置配置文件的默认存储位置更改为非隐藏文件夹?


更新(澄清): 我的意思是我希望能够在设计时运行时更改默认设置中间会话(即,通过编辑配置文件)。但是当使用Settings.settings提供的内置C#持久化机制时,我必须从3个中选择最多2个。我错过了什么吗?还有其他我不知道的选择吗?

[用例: 我想为连接字符串存储一个“默认”数据库名称,但我希望用户能够指定一个运行时不同的数据库(从而成为该用户的“新”默认值)。但我也希望能够覆盖配置文件中的默认值,而无需重新运行或重新构建应用程序。]

[更好的用例:(响应 cmets)

我有一个计算模型,其配置文件包含模型中参数的默认值。用户 A 启动模型并决定更改几个参数的值。该更改需要持续用于该用户 (即在运行时编辑)的所有未来会话。 随后,该用户想要共享修改后的内容与他的团队共享配置文件(例如,通过版本控制存储库或电子邮件)。这将允许用户 B 更新她的默认参数值(以匹配用户 A),而无需在应用程序中手动更改它们(即,在会话之间编辑)。所有这些模块都应该在设计之后发生-时间。]

*我意识到我可以“技术上”在位于隐藏 AppData 文件夹中的 app.exe.config 文件中编辑用户范围的设置,但这是一个隐藏文件,并非所有用户都有足够的权限查看它。 (但请参阅上面的“潜在解决方法”。)

【问题讨论】:

  • 由于我缺乏知识,我还没有克服这种情况。但是使用 app.config 您可以在名称值对中定义您的设置,并可以在运行时相应地选择名称。
  • 在了解C# 后不久,我学到的第一件事就是序列化。虽然字典很好,但它们不适合包含复杂的数据,每次访问数据时都需要强制转换,容易包含错误(尤其是由于用户编辑)......序列化/反序列化使用XmlSerializer 非常简单,所以为什么要麻烦有Settings吗?我发现 json 是保存设置的最佳格式。
  • 如果没有管理员提升,用户应该无法更新适用于所有用户的设置,因为一个用户可能会做出会影响其他用户的不良更改。因此,更改应用程序设置更难是完全有道理的......
  • @kmote:可以在会话之间编辑用户设置!唯一的区别是用户设置存储在用户文件夹中。另见:stackoverflow.com/q/982354/6439999
  • 我觉得这是一个寻找问题的解决方案。为什么您会允许任何用户更改所有用户的应用行为?对我来说听起来很混乱。你有实际用例吗?

标签: c# application-settings settings.settings


【解决方案1】:

您需要做的就是将这两种技术结合起来!

在会话开始时,从配置文件中读取配置的设置,并将其存储到可写的全局静态变量(或任何形式的持久性)中。

然后当用户决定更改此设置时,只需更改设置的值即可。

public static Program {

    public static string ConnectionString { get; set; }

    void Main(string connectionString) {
         ConnectionString = connectionString;
    }

}

public class SomeOtherClass {
     public void SomeOtherMethod () {
         Program.ConnectionString = "new value";
     }
}

这只是您如何使用它的一个非常简单的示例。请注意,您可能选择从应用程序设置中读取默认值,而不是将字符串作为参数传递给程序。您还可能将用户配置的连接字符串存储到某种数据库中,以便每个用户的数据库可能不同。

【讨论】:

  • 恐怕这似乎根本无法解决我的问题。我看不出这种方法与我原始帖子中描述的“用户范围”有何不同。另外,我不确定将数据库连接字符串存储在数据库中有何意义。 (请参阅我帖子中的用例。)
  • 所以您是说您希望能够在应用程序启动时更改默认设置?另外,当然,您对连接字符串是正确的,所以这个例子有点歪。我试图理解的一点是,在存储用户配置的设置时,您可以选择任何持久性方式(除非对存储的访问取决于设置)。
  • 我的意思是,我希望能够在设计时、运行时(即应用程序启动时)、中更改默认设置-会话之间。
  • 在设计期间和会话之间进行更改,我的回答为您的问题提供了答案。因此,当涉及到运行时的更改时,您将不得不编写代码来执行此操作。在这种情况下,您可能必须在应用程序中使用套接字层,以便向客户端发出更改信号。我在您的问题中读到您只想使用内置技术。如果不自己编写一些代码,我认为您无法实现您想要的。
  • "我不确定将数据库连接字符串存储在数据库中有何意义" 大多数较大的应用程序都这样做,它们与包含连接的设置数据库有一个配置文件连接用于工作的各种其他数据库的字符串。
【解决方案2】:

如果您在案例研究中尝试了以下内容并且可以概括它,会怎样?

  1. 只要用户可以更改默认数据库名称,那么这个Key应该定义在用户范围而不是应用范围下
  2. 在安装应用程序时,我假设一个 windows 应用程序,并在第一次运行时,检查 user.config 是否具有数据库名称的值,如果是则继续加载应用程序,否则,转到步骤 3。李>
  3. 向用户显示一个带有默认值的数据库名称的屏幕,用户可以更改设置并确保在此处进行一些验证,完成设置页面后,将它们存储在 user.config 文件中,以便您的应用程序下次运行时,它会找到所需的设置才能正常运行。
  4. 对于管理员权限,您可以显示一个按钮以在运行时更改设置。

我将这种技术用于需要用户定义一些重要细节的所有应用程序,例如“存储图像的位置、数据库名称、连接字符串等”

希望这会给你一个提示或什么

【讨论】:

  • 谢谢,哈迪。这基本上就是我现在正在使用的过程(尽管没有在步骤 2 中进行检查)。我希望找到一种解决方案,允许用户在不运行程序的情况下更改默认值。
猜你喜欢
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2011-02-10
  • 1970-01-01
相关资源
最近更新 更多