从 C# 应用程序中的配置文件检索值不起作用

本文关键字:检索 不起作用 配置文件 应用程序 | 更新日期: 2023-09-27 18:20:38

当我尝试使用配置文件时,我遇到了问题,我在这里和其他地方读过一些帖子但我无法解决工作中的问题,

在我的问题中,我添加了配置。

<?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值始终为空!我确定路径是正常的。

我该如何解决它?

从 C# 应用程序中的配置文件检索值不起作用

从您的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(。我添加了一些琐碎的错误处理,但您需要自己处理错误。我只是在错误时返回以简化代码。该代码具有内联注释,以帮助弄清楚发生了什么。

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 的信息,请参阅此文章。如果由于某种原因下面的代码不起作用,您可以使用上面的代码:

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);
                    }
                }
            }
        }
    }
}

看起来您正在混合两个模型。

  1. 应用程序设置是通过声明派生自 ApplicationSettingsBase 的类来定义的,但通常不会手动执行此操作。 相反,让 VS 通过转到项目的"属性>设置"选项卡来为您创建类。 这会在配置文件中创建一个类似于您发布的 XML 的特殊部分。
  2. 应用设置在特殊的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 的原因是,根据文档,即使指定的路径为 null,也会引发它。 当配置文件中找不到指定的设置时,ConfigurationManager.AppSettings返回 null 引用。 (需要明确的是,在您的情况下找不到它,因为您没有使用如上所示的appSettings配置部分。

听起来指定的文件不存在:D:'ab123'Source'ab123.c

另外,您是否正在尝试存储键值对?像这样的事情呢:

  <setting name="ab123" serializeAs="String">
    <value>D:'ab123'Source'ab123.c</value>
  </setting>
如果您

指的是应用程序的App.Config文件,那么我认为您在设置中额外指定了add元素:

设置应如下所示:

 <setting name="ab123" serializeAs="String">            
       <value>D:''ab123''Source''ab123.c</value>
 </setting>

或使用键/值属性:

<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     
}

我提出了另一个答案。我假设这是您的配置文件的摘录(而不是全部

<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>

我还假设这会返回一个包含您的文件名的 vale

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文件关联。文件关联告诉窗口如何打开此类文件。如果存在文件关联,它将启动指定 D:''ab123''Source''ab123.c 作为其参数的程序(例如,这样的程序将是 Visual Stuido(

如果存在文件关联,则在上述所有假设都正确的情况下,您所做的此调用应该有效。但是,如果没有任何内容可以将.c与程序相关联,则Windows将不知道如何打开它,并且您将收到类似于以下内容的错误:

系统中发生了类型为"System.ComponentModel.Win32Exception"的未处理异常.dll 其他信息:系统找不到指定的文件

检查扩展是否有默认程序的一种方法是简单地打开cmd.exe终端shell并发出以下命令:

D:'ab123'Source'ab123.c

如果这会启动程序并加载您的文件,则关联存在,我的答案将不适用。我建议在有人进行搜索并降落在这里时将此作为答案。这可能对其他人有帮助,但可能不是 OP 的实际问题。