如何在不使用用户设置的情况下在运行时读取/写入 app.config 设置?
Posted
技术标签:
【中文标题】如何在不使用用户设置的情况下在运行时读取/写入 app.config 设置?【英文标题】:How can I read/write app.config settings at runtime without using user settings? 【发布时间】:2011-04-08 00:20:53 【问题描述】:我正在寻找一种方法来存储可以在运行时使用Application Settings 写入的应用程序或机器级别设置。用户设置允许读/写,但应用程序设置不允许。我一直在使用用户设置在运行时保存这样的设置,但由于以下原因,这确实被证明是不切实际的:
机器的所有用户都需要共享设置。 在支持电话中(尤其是在危机情况下),很难向用户/员工解释在哪里可以手动查找和修改这些设置(appdata 是一个隐藏文件夹)。 新版本的应用程序需要使用以前的设置(用户设置似乎被新版本吹走了)。 我们的员工通常会将应用程序复制到一个新文件夹,这也会重置用户设置。无论如何,我们公司的机器都仅供一位用户使用,因此通常不需要用户特定的设置。
否则,我真的很喜欢使用应用程序设置,并希望尽可能继续使用它们。如果设置可以驻留在 与 EXE 相同的文件夹中 (就像好的 ol'ini 文件曾经那样),那将是理想的。
注意:这是一个 WPF 应用程序,而不是 ASP.net Web 应用程序,因此没有 web.config。
【问题讨论】:
将可写设置存储在与 exe 相同的目录中是一个坏主意 - 在 Vista/Win7 上,这需要管理员写入,并且会触发 UAC 并导致您的应用程序运行提升。最好将应用设置存储在其他地方。 @Andy 这对我来说似乎不对。我写了很多程序,在不触发 UAC 的情况下写入与 EXE 相同目录中的 xml 文件。 【参考方案1】:这是允许您更改<AppSettings>
中的条目的方法:
internal static bool SetSetting(string Key, string Value)
bool result = false;
try
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
config.AppSettings.Settings.Remove(Key);
var kvElem= new KeyValueConfigurationElement(Key, Value);
config.AppSettings.Settings.Add(kvElem);
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
result = true;
finally
return result;
// function
注意,我发现更新后有必要刷新appSettings
部分。
该函数在添加键之前删除它以避免重复输入。如果密钥以前不存在,这也有效。如果有任何错误,则返回 false,成功时返回 true。读取设置的方法很简单,只是为了完整性而列出:
internal static string GetSetting(string Key)
string result = null;
try
result = ConfigurationManager.AppSettings[Key];
finally
return result;
// function
注意,我用 try ... finally 块包围它以抑制错误。如果发生任何错误,则 GetSetting 仅返回 null 而 SetSetting 返回 false。这使得处理更容易,但是如果您需要例外,您仍然可以添加
catch (Exception) throw;
向调用者抛出异常。或者,为了调试,您可以添加:
#if DEBUG
catch (Exception ex)
System.Diagnostics.Debug.WriteLine(ex.ToString());
#endif
如果您选择了“调试”配置,它将在 Visual Studio 的 输出 窗口中显示异常,但将继续执行代码。
注意(对类似主题的交叉引用):
applicationSettings 部分不同,因为它区分“用户”和“应用程序”范围,并且支持不同的数据类型,而不仅仅是字符串。如果您想知道如何处理 applicationSettings,可以在此处(在 *** 上)找到它:How to access applicationSettings
如果您不确定应该使用AppSettings
还是applicationSettings
,请在决定之前read this。
如果遇到警告'ConfigurationSettings.AppSettings' is obsolete
,那么this hint can help you.
如果您使用的是 .NET Core 框架,请查看此链接:AppSettings in .NET Core
【讨论】:
【参考方案2】:WPF 应用程序能够像 WinForms 应用程序一样通过
访问 app.config 文件ConfigurationManager.OpenExeConfiguration()
方法。诀窍是在 App.config 文件的 AppSettings 标记中包含您想要访问的值(在 WPF 应用程序中也可用)。
所有这一切的诀窍是确保在修改完属性后调用以下方法:
MyConfig.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("appSettings")
不久前我写了一个完整的“操作方法”来解释这一切here。
【讨论】:
如果用户没有正确的 UAC 权限,这将不起作用。 @JWiley 好点。我猜另一个假设是应用程序安装在可以修改此文件的位置。【参考方案3】:好吧,我还不想在运行时更改应用程序设置(这就是我使用用户设置的目的),但我能够做的是在安装时编写应用程序设置。我想类似的方法可能在运行时起作用。您可以尝试一下,因为似乎没有任何其他支持的解决方案 ATM。
exePath = Path.Combine( exePath, "MyApp.exe" );
Configuration config = ConfigurationManager.OpenExeConfiguration( exePath );
var setting = config.AppSettings.Settings[SettingKey];
if (setting != null)
setting.Value = newValue;
else
config.AppSettings.Settings.Add( SettingKey, newValue);
config.Save();
希望有帮助!
【讨论】:
以上是关于如何在不使用用户设置的情况下在运行时读取/写入 app.config 设置?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用临时文件的情况下在 python 的 tarfile 中写入大量数据
Spring Boot - 如何在不使用 spring 注释的情况下在运行时获取端口
在不使用 X-Windows 的情况下在 Linux 中设置或读取 Caps Lock 状态