.NET 桌面应用程序中的 Settings.settings 与 app.config [重复]

Posted

技术标签:

【中文标题】.NET 桌面应用程序中的 Settings.settings 与 app.config [重复]【英文标题】:Settings.settings vs. app.config in .NET desktop app [duplicate] 【发布时间】:2011-11-19 08:31:32 【问题描述】:

可能重复:What is the difference between app.config file and XYZ.settings file?

我对 Visual Studio 中用于存储和管理桌面应用程序设置的这两种机制的明显冗余感到非常困惑:

您可以使用 XML app.config 文件,将项目添加到 <appSettings> 部分。这些可以使用ConfigurationManager 类从代码中检索。 或者,您可以使用 Settings.settings 文件通过编辑器添加单独的设置。 Visual Studio 将生成一个Settings 类,用于在运行时对设置进行类型安全的检索。

这两种机制似乎服务于相同(或几乎相同)的目的。我知道存在一些差异,但我也对重叠及其后果感到困惑。例如,当我使用 Visual Studio 将设置添加到 Settings.settings 文件时,我放入的所有信息最终也会作为 app.config 文件中的条目。显然,存在一种同步机制:如果我更改了app.config 文件中的设置,Visual Studio 会在我下次在编辑器中打开它时提示我更新Settings.settings 文件。

我的问题是:

为什么是两种机制而不是一种? 使用app.config 而不是Settings.settings 最常见的场景是什么?反之亦然? 如果我的应用程序正在使用Settings.settings,并且我在部署后更改了app.config 中的值,会发生什么情况? Settings.settings 无法同步,因为它已经编译和分发。

注意。我已经搜索过有关此主题的问题,但我更加困惑。例如,this question here 的答案是非常矛盾的,并不能说明太多。

注意 2。我知道 app.config 是设计时文件名,并且我熟悉 Visual Studio 将其复制并重命名为可执行文件夹的动态。

【问题讨论】:

除了西蒙在下面的出色回答之外,请参阅Ruben's answer 对类似问题。 【参考方案1】:

为什么是两种机制而不是一种?

它们有不同的用途。设置 API 提供来自应用程序的读/写访问,而配置是只读的(除非您在代码中编写文件)。

可以为每个用户或每个应用程序定义设置,并且设计为易失性。用户设置被写入 UAC 允许的用户配置文件存储中的隐藏文件夹。

App.config 仅适用于每个应用程序。不会自动获取对 App.config 的更改。它需要重新启动或代码来刷新值。在 UAC 下,不允许用户写入 Program Files 等应用程序目录,因此该文件应视为静态只读。

使用 app.config 最常见的场景是什么? Settings.settings,反之亦然?

您可以在桌面应用程序中使用“设置”来存储用户首选项或在运行时更改的设置。

您可以将 App.config 用于更通用的静态设置,例如连接字符串等,或者用于定义应用中使用的组件的配置。

如果我的应用正在使用 Settings.settings 并且我更改了一个 部署后 app.config 中的值?

如果应用程序被重新部署,那么它将获取新设置,除非机器上已经有用户/应用程序自定义,在这种情况下它将继续使用这些设置,除非您擦除它们。

如果您添加新设置,这些设置将被采纳。事实上,默认值被烘焙到 Settings 类中,因此即使 app.config 为空,Settings 仍然起作用。

【讨论】:

感谢您的详细解答。不过,我对几点感到困惑。首先,我不同意你不能写入 app.config 文件; ConfigurationManager 类提供对任何配置文件的写入权限,它也可以选择用户特定的配置 (msdn.microsoft.com/en-us/library/ms134265.aspx)。我也对您用作示例的场景感到困惑。例如,您会在 Settings 或 app.config 中存储连接字符串吗?为什么?关于我的第三个问题,它是关于更改设置的(而不是添加或删除设置)... ...一旦应用程序被部署,即当它在生产中时。我不想重新编译和重新部署应用程序。例如,如果我的数据库移动到新服务器,我只想更改配置文件中的服务器名称,重新启动应用程序并继续工作;这就是配置文件的重点,对吧?在这种情况下,设置文件中存储的值会发生什么变化?它会被丢弃/取代/忽略吗?谢谢。 是的,可以使用配置管理器更新 web.config,但您必须更改已部署的文件,该文件通常会被 UAC 锁定。它不是为运行时更改而设计的,而设置是。对设置的更改会保存到用户配置文件文件夹中,因此不会出现权限问题。您可以将连接字符串存储在 app.config 中,因为它是静态设置。如果您有自定义版本的设置,它会存储在其他位置,因此部署新更新不会产生任何影响。自定义值将继续覆盖,因此 app.config 更适合 conn 字符串。 不错的投票。设置部署到用户配置文件文件夹,请参阅 here,这是在 UAC 下允许的。应用程序 app.config 甚至应用程序范围的设置都被认为是只读的,因为不允许用户写入 UAC 下的应用程序目录(例如程序文件)。因此,为什么 app.config 不是为运行时更改而设计的,但设置却是。我并不是说它不可能写入 app.config,这只是一种不好的做法,除非你提升应用程序,否则在现实世界中将无法工作。 答案没有任何误导。你问为什么有两种机制,我现在解释了好几次。阅读 UAC。我会向您指出一些文档,但它非常稀缺。如果您仍然不接受我的答案,请创建您自己的答案并将其标记为正确。【参考方案2】:

从.NET Framework的角度来看(暂时不说工具——Visual Studio),历史上只有[app.exe].config(其实就是AppDomain定义为配置文件的东西。名字是由 AppDomain 定义,这就是为什么它是 web.config 用于 Web 应用程序...)和 machine.config。 'app' 与应用程序一起部署,'machine' 用于整机。对于普通用户,它们应该是“相当”只读的。可以更改它们,但不是这个想法。

但是我怎样才能保存最终用户的偏好呢?这就是引入 [user].config 的原因(我相信 .NET 2)。官方文档是这样说的:

最初随 .NET 发布的配置系统 框架支持提供静态应用配置数据 通过本地计算机的 machine.config 文件或在 与应用程序一起部署的 app.exe.config 文件。这 LocalFileSettingsProvider 类在 以下方式:

1) 应用程序范围的设置可以存储在 machine.config 中 或 app.exe.config 文件。 Machine.config 始终是只读的,而 app.exe.config 受安全考虑限制为只读 适用于大多数应用程序。

2) 用户范围的设置可以存储在 app.exe.config 文件中,其中 如果它们被视为静态默认值。

3) 非默认用户范围的设置存储在一个新文件中, user.config,其中 user 是当前人员的用户名 执行应用程序。您可以为用户范围指定默认值 使用 DefaultSettingValueAttribute 设置。因为用户范围 设置在应用程序执行期间经常改变,user.config 是 总是读/写。

所以从 .NET Framework 的角度来看,只有一种 3 层机制。

现在,Visual Studio 只是尝试通过为最终的读/写设置生成类型安全的代码来帮助您。大多数情况下,[user].config 文件不存在,设置值将由 DefaultSettingValueAttribute 中的内容定义(为每个设置定义),或者使用在 app.config 中静态定义的内容。这就是为什么 Visual Studio 还会更新 app.config 文件,以便您可以为设置定义静态默认值。但是你可以完全删除所有 app.config 的东西。

【讨论】:

谢谢,西蒙。您建议在哪种情况下使用这两种机制? Simon,问题是关于Settings.settings 文件和Visual Studio 的Settings 类。我没有在您的回答中看到这两个是如何处理的。相反,您提到了user.config。这两个“设置”概念是否与user.config 相关?还是它们来自较旧或较新的替代机制? @ToolmakerSteve - 设置是一个全局概念。每个设置都有一个范围。可以保存用户范围的设置。保存后,将其写入 user.config。 这个答案让我感觉很不满意,因为它甚至没有提到Settings.settings 如果我再次问这个问题,它将被标记为这个问题和它被标记为重复的那个的重复。

以上是关于.NET 桌面应用程序中的 Settings.settings 与 app.config [重复]的主要内容,如果未能解决你的问题,请参考以下文章

有没有人使用过嵌入在 .NET 桌面应用程序中的 Open Office?

urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误

urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误

urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误

urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误

urlmon.dll FindMimeFromData() 在 64 位桌面/控制台上完美运行,但在 ASP.NET 上生成错误