外部修改C#Winform程序配置文件后Winform程序通过ConfigurationManager.AppSettings.Get方法读取没有变化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了外部修改C#Winform程序配置文件后Winform程序通过ConfigurationManager.AppSettings.Get方法读取没有变化相关的知识,希望对你有一定的参考价值。

如题。运行Winform程序,读取配置文件中AppSetting的某个节点的值,比如得到“0" ;然后用记事本打开并修改这个节点为”1“并保存,再次用Winform程序读取这个节点,还是得到”0“,重启应用程序再读取就可以得到"1"。这是为什么?怎样才能实现修改配置文件后不重启程序得到修改后的值?

这是因为你程序运行时,已经将配置文件中的信息加载到了内存中,之后每次读取时如果缓存中已经存在对应的值,则直接使用此值,否则才会从文件中读配置,这样做的好处是减少了系统和文件甚至与数据库的交互次数;
在web程序中配置文件更改后,应用程序会自动重启一次,于是配置会自动生效。但winform程序没有这个机制,于是Configuration.ConfigurationManager调用配置不会自动更新。
所以建议你手动实现调用配置的逻辑,代码如下:
public string ReadAppSetting(string key)

string xPath = "/configuration/appSettings//add[@key='"+key+"']";
XmlDocument doc = new XmlDocument();
string exeFileName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
doc.Load(exeFileName + ".exe.config");
XmlNode node = doc.SelectSingleNode(xPath);
return node.Attributes["value"].Value.ToString();

这样做的话就不存在缓存的问题了,希望能对你有所帮助。
参考技术A winform本来就有这种机制,如果你要立即变化,就得自己建配置文件,然后做设置
winform默认的config文件其实是在运行的时候转化成了:程序名称.exe.config,其实程序修改配置文件是对这个文件进行修改,当你修改完的时候,去看 程序名称.exe.config,你会发现你的设置没有保存

如何编辑外部 web.config 文件?

【中文标题】如何编辑外部 web.config 文件?【英文标题】:How to edit an external web.config file? 【发布时间】:2010-11-20 23:42:45 【问题描述】:

我正在尝试编写一个能够编辑已安装 Web 应用程序的 web.config 文件的 winform 应用程序。 我已经阅读了 ConfigurationManager 和 WebConfigurationManager 类方法,但我不确定如何打开 Web 应用程序的配置文件并对其进行编辑。

我正在寻找一种不需要我将配置文件作为常规 XmlDocument 加载的方法,但如果这是唯一可用的选项,我愿意这样做。

任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

所有app.configweb.config 都只是XML 文件。您可以使用 XMLDocument、XMLWriter 等打开和编辑它们。

【讨论】:

该问题明确表示他们不想使用通用 XMLDocument 对象(这是一个好主意,因为您不需要重新发明***)。【参考方案2】:

好的,这就是答案,我有完全相同的情况。我想写一个 winforms 应用程序来允许普通用户更新 web.config。您必须以一种愚蠢的方式获取配置...

// the key of the setting
string key = "MyKey";

// the new value you want to change the setting to
string value = "This is my New Value!";

// the path to the web.config
string path = @"C:\web.config";

// open your web.config, so far this is the ONLY way i've found to do this without it wanting a virtual directory or some nonsense
// even "OpenExeConfiguration" will not work
var config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap()  ExeConfigFilename = path , ConfigurationUserLevel.None);

// now that we have our config, grab the element out of the settings
var element = config.AppSettings.Settings[key];

// it may be null if its not there already
if (element == null)

 // we'll handle it not being there by adding it with the new value
 config.AppSettings.Settings.Add(key, value);

else

 // note: if you wanted to you could inspect the current value via element.Value

 // in this case, its already present, just update the value
 element.Value = value;


// save the config, minimal is key here if you dont want huge web.config bloat
config.Save(ConfigurationSaveMode.Minimal, true);

这是一个例子

之前:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="MyKey" value="OldValue" />
  </appSettings>
  <connectionStrings>
    <add name="myConnString" connectionString="blah blah blah" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

之后:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="MyKey" value="This is my New Value!" />
  </appSettings>
  <connectionStrings>
    <add name="myConnString" connectionString="blah blah blah" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <trust level="Full" />
    <webControls clientScriptsLocation="/aspnet_client/0/1/" />
  </system.web>
</configuration>

请注意,如果您给它一个无效的路径,它只会在该路径/文件名处创建一个配置文件。基本上,首先对其进行 File.Exists 检查

顺便说一句,当您使用它时,您可以在 web.config 中编写一个代表您的设置的类。完成此操作后,编写您的 getter/setter 以读取/写入 web.config 中的设置。完成此操作后,您可以将此类添加为数据源并将数据绑定控件拖到您的 winform 上。这将为您提供一个完全数据绑定的 winform web.config 编辑器,您可以在几分钟内轻松完成。 我有一个工作中的例子,我明天会发布。

功能齐全的winforms解决方案

所以这是编写 GUI 来编辑 web.config 的一个相对简单的解决方案,有些人可能会说它过于复杂,而记事本也可以,但它适用于我和我的观众。

它基本上如上所述工作,我编写了一个具有我想要作为属性的配置点的类。 ctor 从路径打开文件,getter / setter 将数据从返回的配置对象中拉出,最后它有一个保存方法将其写出。有了这个类,我可以将类添加为数据源并将绑定控件拖放到 winforms 上。从那里你所要做的就是连接一个按钮来调用你的类的保存方法。

配置类

using System.Configuration;

// This is a representation of our web.config, we can change the properties and call save to save them
public class WebConfigSettings

 // This holds our configuration element so we dont have to reopen the file constantly
 private Configuration config;

 // given a path to a web.config, this ctor will init the class and open the config file so it can map the getters / setters to the values in the config
 public WebConfigSettings(string path)
 
  // open the config via a method that we wrote, since we'll be opening it in more than 1 location
  this.config = this.OpenConfig(path);
 

 // Read/Write property that maps to a web.config setting
 public string MySetting
 
  get  return this.Get("MySetting"); 
  set  this.Set("MySetting", value); 
 

 // Read/Write property that maps to a web.config setting
 public string MySetting2
 
  get  return this.Get("MySetting2"); 
  set  this.Set("MySetting2", value); 
 

 // helper method to get the value of a given key
 private string Get(string key)
  
  var element = config.AppSettings.Settings[key];

  // it may be null if its not there already
  if (element == null)
  
   // we'll handle it not being there by adding it with the new value
   config.AppSettings.Settings.Add(key, "");

   // pull the element again so we can set it below
   element = config.AppSettings.Settings[key];
  
  return element.Value;
 

 // helper method to set the value of a given key
 private void Set(string key, string value)
 
  // now that we have our config, grab the element out of the settings
  var element = this.config.AppSettings.Settings[key];

  // it may be null if its not there already
  if (element == null)
  
   // we'll handle it not being there by adding it with the new value
   config.AppSettings.Settings.Add(key, value);
  
  else
  
   // in this case, its already present, just update the value
   element.Value = value;
  
 

 // Writes all the values to the config file
 public void Save()
 
  // save the config, minimal is key here if you dont want huge web.config bloat
  this.config.Save(ConfigurationSaveMode.Minimal, true);
 

 public void SaveAs(string newPath)
 
  this.config.SaveAs(path, ConfigurationSaveMode.Minimal, true);

  // due to some weird .net issue, you have to null the config out after you SaveAs it because next time you try to save, it will error
  this.config = null;
  this.config = this.OpenConfig(newPath);
 

 // where the magic happens, we'll open the config here     
 protected Configuration OpenConfig(string path)
 
  return ConfigurationManager.OpenMappedExeConfiguration(
        new ExeConfigurationFileMap()   ExeConfigFilename = path , 
        ConfigurationUserLevel.None);   
 

构建,然后从那里您可以转到您的 winform 设计器,转到数据 > 显示数据源 (Shift+Alt+D)。右击>添加新数据源,如图所示添加为对象

Data Source Configuration Wizard 1 of 2 http://img109.imageshack.us/img109/8268/98868932.png

Data Source Configuration Wizard 2 of 2 http://img714.imageshack.us/img714/7287/91962513.png

将它(WebConfigSettings,最顶部)拖到 winform 上。就我而言,我将删除导航器,因为它是一个列表,而我只有一个。

Freshly added databound controls http://img96.imageshack.us/img96/8268/29648681.png

你应该在设计器的底部有类似 webConfigSettingsBindingSource 的东西(如下图所示)。转到代码视图并将ctor 更改为此

public Form1()

    InitializeComponent();

    // wire up the actual source of data
    this.webConfigSettingsBindingSource.DataSource = new WebConfigSettings(@"c:\web.config");

在您的 winform 中添加保存按钮

Save button added http://img402.imageshack.us/img402/8634/73975062.png

添加以下事件处理程序

private void saveButton_Click(object sender, EventArgs e)

    // get our WebConfigSettings object out of the datasource to do some save'n
    var settings = (WebConfigSettings)this.webConfigSettingsBindingSource.DataSource;

    // call save, this will write the changes to the file via the ConfigurationManager
    settings.Save();

现在,您有了一个不错的简单数据绑定 web.config 编辑器。要添加/删除字段,您只需修改 WebConfigSettings 类,刷新数据源窗口中的数据源(构建后),然后将新字段拖放到 UI 上。

您仍然需要连接一些代码来指定要打开的 web.config,对于这个示例,我只是硬编码了路径。

这里最酷的地方在于 GUI 添加的所有价值。您可以轻松添加目录或文件浏览器对话框,您可以拥有连接字符串测试器等。所有这些都非常容易添加并且对最终用户非常强大。

【讨论】:

我给你一个“投票”。虽然您的帖子只是回答了这个问题。【参考方案3】:

我强烈建议您使用 XElement 并启用 LINQ (LINQ to XML)。

例如,您想更改connectionString。这种代码就够了

var connString = from c in webConfigXElement.appSettings.connectionString
                        where c.name == "myConnection"
                        select c;

现在您可以完全控制&lt;connectionString /&gt; 元素,并且可以用它做任何您想做的事情。

我将您推荐给MSDN 进行学习,同时推荐Kick Start 进行即时工作。

希望这可以帮助您轻松地完全控制您的.xml

【讨论】:

他明确表示他不想这样做。这里的每个人都知道 web.config 是 xml,您可以以任何您认为合适的方式打开和编辑它。 @Allen ConfigurationManager 类确实用于修改/添加。您还应该记住ConfigurationManager 类可以控制AppSettingsConnectionStringsXmlDocument 是痛苦的,ConfigurationManager.config 文件的解决方案之一。相信我LINQ to XML 在您需要电源时会更方便。顺便说一句,艾伦,你应该知道你的举止。您应该知道何时投赞成票投反对票干杯【参考方案4】:

在这里,我编写了一个玩具应用程序(VB.NET Windows 客户端),它使用树/网格来编辑 XML 文件以进行导航和编辑。

你可能会从中得到一些想法。它的 VS 项目文件是 here 或者只是一个安装它的 MSI 是 here,如果你想在你的 web.config 上试用它。

它将文件加载到 DataSet (DataSet.ReadXML()) 中,后者将其解析为 DataTables,然后显示并允许在标准 DataGrid 中编辑内容。然后它将编辑的内容保存回 XML 文件 (DataSet.WriteXML())。

【讨论】:

以上是关于外部修改C#Winform程序配置文件后Winform程序通过ConfigurationManager.AppSettings.Get方法读取没有变化的主要内容,如果未能解决你的问题,请参考以下文章

C#winform 关于调用外部程序的问题

如何修改C#winform程序图标

有关C#winform的调用外部程序的问题

winform程序退出保存的问题

WPF做的Winform 怎样从外部xml文件读取样式

SpringBoot:加载和读取jar包外面的资源文件