65.9K
CodeProject 正在变化。 阅读更多。
Home

从配置文件加载设置

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (9投票s)

2012年5月10日

CPOL

3分钟阅读

viewsIcon

76190

downloadIcon

2967

如何在不重新编译代码的情况下从 app.config 加载设置。

引言

本文展示了如何在 Visual Studio 中从配置文件加载应用程序设置,而无需重新编译代码。如果您的项目是单个 EXE,则 .NET 会自动提供此功能。但是,当我尝试用 DLL 做同样的事情时,此功能对我不起作用,应用程序启动时未加载配置文件。有很多相关的文章,但我找不到随时可用的解决方案。因此,我决定花一些时间贡献这篇文章。我希望它对像我一样的人有用...

背景  

最近,我一直在开发一个需要高度可配置性的插件(DLL),包括用户和应用程序级别。我的首选是利用 .NET Framework 提供的 app.config 机制。使用此机制,可以在 Visual Studio 前端方便地定义应用程序和用户设置。并且这些设置可以通过 My.Settings 对象立即在代码中使用。此外,系统会自动创建一个与二进制文件一起存储的配置文件。如果需要更新 My.Settings,应该可以使用 Reload() 方法。到目前为止,一切都很好...不幸的是,我发现应用程序启动时不会加载配置文件。这意味着如果用户手动修改配置文件,则不会反映新值。为了更改配置设置,用户必须使用 Visual Studio 然后重新编译代码! Frown | <img src=. 所以,如果我们想在大量的用户/机器之间重新分发新的配置文件,则不会使用新的设置。我简直不敢相信这对 Microsoft 的人来说是正确的行为,所以我开始寻找解决方案。在花了一些时间寻找解决方案后,我决定编写自己的代码来重新加载 .NET 提供的配置文件中的设置值。

使用代码 

为了演示这个概念,我用 VB.NET 创建了一个小型测试应用程序。该应用程序从配置文件加载设置,并将其显示为属性网格。 如下所示:

用户可以通过文件->编辑打开配置文件进行编辑,在他喜欢的编辑器中修改设置,然后使用文件->重新加载将这些值重新加载到应用程序中。

 

 



配置文件解析器的实现在 SettingsHelper.vb 模块中提供。必须从检索配置文件句柄开始。

 Dim config = ConfigurationManager.OpenExeConfiguration(My.Application.Info.AssemblyName + ".exe")   

可以如下访问配置文件的各个部分:

 Dim settingsSection As ClientSettingsSection = config.GetSection(sectionName) 

然后,需要复制每个设置并将其从字符串转换为其实际类型。可以从 My.Settings 项目中恢复此类型。

 For Each st As SettingElement In settingsSection.Settings
 
            'get setting name and value
            Dim name As String = st.Name
            Dim value As String = st.Value.ValueXml.InnerText
 
            'skip unknown settings
            Dim mySettingsItem = My.Settings.Item(name)
            If mySettingsItem Is Nothing Then
                Continue For
            End If
 
            'get setting type
            Dim itemType = mySettingsItem.GetType
 
            'check setting type name
            'some types require special treatment
            If itemType.Name = "StringCollection" Then
 
                mySettingsItem.Clear()
 
                'populate new string collection
                Dim arrayOfString = st.Value.ValueXml.SelectNodes("ArrayOfString/string")
                For i = 0 To arrayOfString.Count - 1
                    Dim newString = arrayOfString.Item(i).InnerText
                    mySettingsItem.Add(newString)
                Next
 
            ElseIf itemType.Name = "Color" Then
                If value.Contains(",") Then
                    Dim rgbValues As String() = value.Split(",")
                    Dim r As Integer = Convert.ToInt32(rgbValues(0))
                    Dim g As Integer = Convert.ToInt32(rgbValues(1))
                    Dim b As Integer = Convert.ToInt32(rgbValues(2))
                    mySettingsItem = Color.FromArgb(r, g, b)
                Else
                    mySettingsItem = Color.FromName(value)
                End If
            Else
 
                'try to cast
                Try
                    mySettingsItem = CTypeDynamic(value, itemType)
                Catch ex As Exception
                    MsgBox("Cannot read " + name + " from config file!", MsgBoxStyle.Critical)
                    Continue For
                End Try
 
            End If
 
            'update My.Settings
            My.Settings.Item(name) = mySettingsItem
        Next 

请注意,某些类型无法直接转换,需要特殊处理。在当前的示例中,我们处理最常用的 StringCollectionColor。但是,您可能需要扩展此代码以处理更复杂的类型。一旦成功检索到项目值,它将被设置回 My.Settings 对象中。

兴趣点 

重要的是要记住,Visual Studio 创建的原始 app.config 文件在代码编译后被复制到 Bin 目录中。根据您的情况,您可能不想覆盖 USER 设置,而只想覆盖 APPLICATION 设置。用户设置允许为每个用户自定义应用程序行为,因此这些设置的值是单独存储的。





© . All rights reserved.