在运行时或安装时修改 App.config 中的配置部分

发布于 2024-08-18 22:15:32 字数 1775 浏览 8 评论 0原文

我有一个使用 Visual Studio 2008 的发布 (ClickOnce) 系统部署的 WinForms 应用程序。在应用程序的 app.config 文件中,我有一个第三方组件所需的配置部分,其形式如下:

<section name="thirdPartySection"
type="System.Configuration.NameValueSectionHandler" />

该部分因此不在 appSettings 中,看起来像:

<thirdPartySection >
  <add key="someKey" value="someValue" />
</thirdPartySection >

我明白关键/值对是一个NameValueCollection。我面临的问题是,我希望在部署时或运行时更改该值(对我来说都可以),以便 someValue 将是 someOtherValue< /code> 基于安装的环境。

目前,我在运行时进行了一些其他配置更改,但这些更改位于 AppSettings 部分,因此很容易获取。我在寻找解决方案时找到了许多参考文献,但它们似乎依赖于具有自定义类的部分,而不是我面临的 NameValueCollection。

有谁知道修改此数据的最佳方法?使用 ConfigurationManager.RefreshSection() 进行运行时更改将更符合我当前的代码,但我也愿意在安装阶段接受建议。

编辑:这在运行时起作用。这就是我处理旧配置覆盖的方式。

Configuration config = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);

config.AppSettings.Settings["Main.ConnectionString"].Value = 
    PolicyTrackerInfo.ConnectionString;

config.AppSettings.Settings["Main.linq"].Value = 
    PolicyTrackerInfo.LinqConnectionString;


config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

我尝试对另一部分做同样的事情:

string overwriteXml = config.GetSection("thirdPartySection")
    .SectionInformation.GetRawXml();

XmlDocument xml = new XmlDocument();
xml.LoadXml(overwriteXml);
XmlNode node = xml.SelectSingleNode("thirdPartySection/add");
node.Attributes["value"].Value = PolicyTrackerInfo.OverwriteString;

到目前为止,一切都很好。但是,我没有看到允许我用修改后的数据替换旧 XML 的方法。 在运行时可能吗?

顺便说一句:我尝试手动修改 app.config.deploy 文件。这只会给我一个验证错误,因为安装程序检测到修改并且拒绝继续。我真的很喜欢自动部署,而且之前的覆盖效果很好。

I have an WinForms application that is deployed using Visual Studio 2008's publish (ClickOnce) system. Within the application's app.config file I have a config section that is required by a third party component that has the form:

<section name="thirdPartySection"
type="System.Configuration.NameValueSectionHandler" />

The section is thus not in the appSettings and looks like:

<thirdPartySection >
  <add key="someKey" value="someValue" />
</thirdPartySection >

I understand that the key/value pairs are a NameValueCollection. The problem I face is that I wish to change the value either a deployment time or at runtime (either is fine with me) so that someValue will be someOtherValue based on the environment installed in.

Currently I make some other config changes at runtime, but those are in the AppSettings section, and thus easy to get at. I have found many references in my search for a solution, but they seem to rely on the section having a custom class, not the NameValueCollection that I'm faced with.

Does anyone know the best way to modify this data? A runtime change with a ConfigurationManager.RefreshSection() would be more in line with my current code, but I'm open to suggestions during the install phase as well.

Edit: This works at runtime. This is how I was handling the old configuration overrides.

Configuration config = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);

config.AppSettings.Settings["Main.ConnectionString"].Value = 
    PolicyTrackerInfo.ConnectionString;

config.AppSettings.Settings["Main.linq"].Value = 
    PolicyTrackerInfo.LinqConnectionString;


config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

My attempt to do the same for another section:

string overwriteXml = config.GetSection("thirdPartySection")
    .SectionInformation.GetRawXml();

XmlDocument xml = new XmlDocument();
xml.LoadXml(overwriteXml);
XmlNode node = xml.SelectSingleNode("thirdPartySection/add");
node.Attributes["value"].Value = PolicyTrackerInfo.OverwriteString;

So far, so good. However, I don't see a method that allows me to replace the old XML with my modified data. Is it possible at runtime?

As an aside: I tried modifying the app.config.deploy file by hand. That just gives me a validation error as the modification is detected by the installer and it refuses to proceed. I really like the auto deploy, and the prior override worked great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北陌 2024-08-25 22:15:32

您可以做的一件事是在代码中添加首次运行部分,以执行其他设置,例如修改应用程序配置文件。为了检测是否需要完成此设置,您的第三方配置部分可能会预先填充虚拟值,您的应用程序会将这些虚拟值识别为属于新安装。例如,您的配置文件可能如下所示:

<thirdPartySection>
    <add key="someKey" value="#NEEDS_INITIALIZED#" />
</thirdPartySection >

并且您的 Main 方法可能如下所示:

static public void Main(params string[] args)
{
    const string uninitializedValue = "#NEEDS_INITIALIZED#";

    // Load the third-party config section (this assumes it inherits from
    // ConfigurationElementCollection
    var config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    var section = config.GetSection("thirdPartySection") 
        as NameValueConfigurationCollection;
    var setting = section["someKey"];
    if (setting.Value == uninitializedValue)
    {
        setting.Value = PolicyTrackerInfo.OverwriteString;
        config.Save();
    }
}

One thing you could do is add a first-time-running section to your code that does additional setup, such as modifying the application config file. To detect whether this setup needs to be done, your third-party config section could come pre-populated with dummy values that your application would recognize as belonging to a new install. For example, your config file could look like this:

<thirdPartySection>
    <add key="someKey" value="#NEEDS_INITIALIZED#" />
</thirdPartySection >

And your Main method could look something like this:

static public void Main(params string[] args)
{
    const string uninitializedValue = "#NEEDS_INITIALIZED#";

    // Load the third-party config section (this assumes it inherits from
    // ConfigurationElementCollection
    var config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    var section = config.GetSection("thirdPartySection") 
        as NameValueConfigurationCollection;
    var setting = section["someKey"];
    if (setting.Value == uninitializedValue)
    {
        setting.Value = PolicyTrackerInfo.OverwriteString;
        config.Save();
    }
}
青朷 2024-08-25 22:15:32

为了提出人们可以投票赞成或反对的想法(除了围绕这个问题的风滚草之外,我没有见过太多其他的东西),我正在考虑使用这里发布的技术:http://www.devx.com/dotnet/Article/10045

基本思想是让 ClickOnce 部署一个 shim 应用程序,该应用程序只会对主应用程序进行 XCOPY 部署(因为它不使用 app.config 文件,所以我只能使用标准 XML 修改技术并完成它)。

或者,由于此应用程序是从网络部署的,我可以将程序集放在网络上并使用权限系统授予其对其所需的文件夹和数据库的访问权限。有什么想法吗?

For the sake of putting forward an idea that people can vote up or down (not that I have seen much other than tumbleweed around this question), I'm thinking of using the technique posted here: http://www.devx.com/dotnet/Article/10045

The basic idea is to make ClickOnce deploy a shim application which will just do an XCOPY deployment of the main application (and as it isn't using the app.config file I can just use standard XML modification techniques and be done with it).

Alternatively, as this application is deployed from the network, I may just put the assembly on the network and work with the permission system to grant it access to the folders and database it requires. Any thoughts?

感悟人生的甜 2024-08-25 22:15:32

我会编写一个 自定义安装程序 并且,在 AfterInstall 事件中,使用上面的 XML 机制修改配置文件。但我不知道它如何或是否适用于 ClickOnce。

I would write a custom installer and, in the AfterInstall event, modify the config file using the XML mechanisms you have above. I don't know, though, how or if that works with ClickOnce.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文