从 C# 应用程序中的配置文件中检索值不起作用
Posted
技术标签:
【中文标题】从 C# 应用程序中的配置文件中检索值不起作用【英文标题】:Retrieving Value from Config file in C# Application Doesn't Work 【发布时间】:2014-10-28 15:37:25 【问题描述】:我在尝试使用配置文件时遇到问题, 我在这里和其他地方读过一些帖子 但我不能解决工作中的问题,
在我的问题中,我已经添加了配置。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CA.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<CA.Properties.Settings>
<appSettings>
<add key="ab123" value="D:\ab123\Source\ab123.c" />
</appSettings>
</CA.Properties.Settings>
</userSettings>
</configuration>
在文档中声明
string ab123 = ConfigurationManager.AppSettings["ab123"];
但在侧面,我显示错误是 " win32 异常未处理 - 系统找不到指定的文件"
System.Diagnostics.Process.Start(ConfigurationManager.AppSettings["ab123"]);
当我运行这段代码时,ab123
的值始终为空!
我确定路径是正常的。
我该如何解决?
【问题讨论】:
关注问题。首先获取配置值,然后尝试启动一个进程。你没有得到一个值,这是一个合理的问题,但进程启动失败只是一个副产品。对于您的问题本身,请遵循此处给出的一些答案:***.com/questions/1189364/… @Jonesy 问题是关于标准配置键,而不是自定义配置部分... @OferZelig 意思是拿不到值? 在您的 xml 文件中,我不明白<value />
在配置管理器的上下文中做了什么。如果删除会怎样?
@kyoko 如果与之前的错误完全相同,那么肯定有其他问题。请尝试在short but complete sample 中重现问题,包括所有 C# 代码和 XML 配置。
【参考方案1】:
从您的 xml 配置文件中可以看出,您实际上是在尝试使用用户设置而不是应用程序设置,并且您混淆了一些想法。我认为更正确的配置版本可能是:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="CA.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<CA.Properties.Settings>
<setting name="ab123" serializeAs="String">
<value>D:\ab123\Source\ab123.c</value>
</setting>
</CA.Properties.Settings>
</userSettings>
</configuration>
唯一显着的区别是您定义设置的方式。比如我把它改成:
<setting name="ab123" serializeAs="String">
<value>D:\ab123\Source\ab123.c</value>
</setting>
您可以像这样使用不同的name
创建更多设置
客户端代码有点不同,因为它必须找到用户设置,找到程序属性设置,然后查询密钥(如ab123
)。我添加了一些微不足道的错误处理,但您需要自己处理错误。我只是简单地返回错误以简化代码。该代码具有内联 cmets 以帮助弄清楚发生了什么。
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.IO;
namespace ConsoleApplication1
class Program
static void Main(string[] args)
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Retrieve the userSettings gorup
ConfigurationSectionGroup group = config.SectionGroups[@"userSettings"];
if (group == null) return;
// Get the program settings
ClientSettingsSection clientSection = group.Sections["CA.Properties.Settings"] as ClientSettingsSection;
if (clientSection == null) return;
// This retrieves the value associated with the key
string sFileName = clientSection.Settings.Get("ab123").Value.ValueXml.InnerText;
// Check if ab123 has a value and the file exists
if (!string.IsNullOrEmpty(sFileName) && System.IO.File.Exists(sFileName))
using (StreamReader sr = new StreamReader(sFileName))
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
System.Diagnostics.Debug.WriteLine(line);
如果您使用 Settings.settings 创建和删除设置,那么代码可以简化为这样,因为 Visual Studio 将为您的设置对象创建在设计时和运行时访问的绑定。有关通过 Visual Studio IDE 使用 Settings.settings 的信息,请参阅article。如果由于某种原因下面的代码不起作用,您可以使用上面的代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.IO;
namespace ConsoleApplication1
class Program
static void Main(string[] args)
string sFileName = Properties.Settings.Default.ab123;
// Check if ab123 has a value and the file exists
if (!string.IsNullOrEmpty(sFileName) && System.IO.File.Exists(sFileName))
using (StreamReader sr = new StreamReader(sFileName))
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
System.Diagnostics.Debug.WriteLine(line);
【讨论】:
【参考方案2】:看起来您正在混合使用两个模型。
-
Application Settings 是通过声明派生自 ApplicationSettingsBase 的类来定义的,尽管通常您不会手动执行此操作。相反,让 VS 通过转到项目的 Properties > Settings 选项卡为您创建类。这会在您的配置文件中创建一个类似于您发布的 XML 的特殊部分。
App Settings 在特殊的
appSettings
配置部分中定义。正如您所做的那样,只能通过ConfigurationManager.AppSettings
属性访问这些类型的设置。请参阅下面的 XML 示例。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ab123" value="D:\ab123\Source\ab123.c" />
</appSettings>
</configuration>
您收到 Win32Exception 的原因是,根据documentation,即使指定的路径为空,它也会被抛出。当在配置文件中找不到指定的设置时,ConfigurationManager.AppSettings
返回一个空引用。 (为了清楚起见,在您的情况下找不到它,因为您没有使用上面显示的 appSettings
配置部分。)
【讨论】:
我试了但是有问题 "" win32 Exception was unhandled - System can not find the file specified"" 你把它放在你的.exe项目的app.config文件中了吗?为 .dll 项目生成的配置文件完全没有关联。 是的,因为您使用的是appSettings
,就像我在回答中描述的那样。请注意,它与setting
不同,正如您在答案的 cmets 中向我描述的那样,这不是 OP 发布的内容。
是的,我也有点困惑。我认为此时 OP 需要遵循我的建议并发布一个简短但完整的示例。根据对另一个答案的最新评论,他似乎正在尝试使用Start
来“读取”文件,所以这里有更大的问题......【参考方案3】:
听起来指定的文件不存在:D:\ab123\Source\ab123.c
另外,您是否尝试存储键值对?像这样的东西呢:
<setting name="ab123" serializeAs="String">
<value>D:\ab123\Source\ab123.c</value>
</setting>
【讨论】:
我检查,文件在这个路径中 我修复了 xml 但不是这个问题 尝试在string ab123 = ConfigurationManager.AppSettings["ab123"];
这一行之后设置断点,看看ab123的值是多少(确保它是一个有效的路径)。【参考方案4】:
如果您指的是应用程序的App.Config
文件,那么我认为您在设置中还指定了add
元素:
设置应如下所示:
<setting name="ab123" serializeAs="String">
<value>D:\\ab123\\Source\\ab123.c</value>
</setting>
或者使用 Key/Value 属性:
<appSettings>
<add key="ab123" value="D:\\ab123\\Source\\ab123.c"/>
</appSettings>
代码:
var appSettings = ConfigurationManager.AppSettings;
string sPath = appSettings["ab123"];
//furthermore check for path validity
if(!string.IsNullOrEmpty(sPath) && System.IO.File.Exists(sPath))
//System.Diagnostics.Process.Start(sPath);
string[] readText = System.IO.File.ReadAllLines(sPath); //to read the lines in string array
【讨论】:
我试试你的方法 可以运行但是打不开文件 你指的路径不可执行?如果您想打开并阅读内容,则可以使用不同的方式。 这应该是另一个问题。 打开的文件没有使用“System.Diagnostics.Process.Start”? 是的,检查我已经阅读了字符串数组中的所有内容文件。您也可以使用StreamReader
。有许多不同的方法可用。【参考方案5】:
我提出另一个答案。我认为这是您的配置文件的摘录(而不是全部内容
<setting name="ab123" serializeAs="String">
<add key="ab123" value="D:\ab123\Source\ab123.c"/>
</setting>
这是错误的,当我创建我的配置文件时,它看起来像这样,但不知道这与您的示例不同:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ab123a" value="D:\ab123\Source\ab123.c" />
</appSettings>
</configuration>
我还将假设这会返回一个包含您的文件名的值
string ab123 = ConfigurationManager.AppSettings["ab123"];
您已声明文件 D:\ab123\Source\ab123.c 存在。所以我会假设这是真的。
如果所有这些都是真的,我可以看到她的一个问题是您没有将可执行文件或批处理/cmd 文件指定给 System.Diagnostics.Process.Start
。你的代码相当于
ConfigurationManager.AppSettings("D:\\ab123\\Source\\ab123.c");
这是可以接受的,但 Windows 会发现 ab123.c 不是可执行程序。然后它会在 Windows 注册表中查找 .c
文件关联。文件关联告诉 Windows 如何打开这样的文件。如果存在文件关联,它将启动指定 D:\ab123\Source\ab123.c 作为其参数的程序(例如,这样的程序是 Visual Stuido)
如果存在文件关联,如果上述所有假设都正确,则您所做的此调用应该可以工作。但是,如果没有任何东西可以将.c
与某个程序相关联,那么 Windows 将不知道如何打开它,您将收到类似以下的错误:
System.dll 中出现“System.ComponentModel.Win32Exception”类型的未处理异常 附加信息:系统找不到指定的文件
检查扩展是否有默认程序的一种方法是简单地打开 cmd.exe 终端外壳并发出以下命令:
D:\ab123\Source\ab123.c
如果启动一个程序并加载您的文件,则关联存在,我的回答将不适用。如果有人在此处搜索并登陆,我建议将此作为答案。这可能对其他人有帮助,但可能不是 OP 的实际问题。
【讨论】:
ConfigurationManager.AppSettings
不会从您发布的配置部分检索值。该部分仅适用于应用程序设置。看我的回答。
我在 App.config 中添加了 <setting name="ab123" serializeAs="String"> <add key="ab123" value="D:\ab123\Source\ab123.c"/> </setting>
,它确实有效。
配置文件在哪里?
在<configuration>
和</configuration>
之间
嗯?配置下没有“设置”部分。见the docs。注意有一个appSettings
部分。以上是关于从 C# 应用程序中的配置文件中检索值不起作用的主要内容,如果未能解决你的问题,请参考以下文章