gpt4 book ai didi

c# - 如何告诉应用程序从我的自定义 app.config 文件而不是默认文件中读取

转载 作者:行者123 更新时间:2023-12-02 14:42:46 24 4
gpt4 key购买 nike

假设我正在创建一个名为 ConsoleApp2 的应用。

由于我正在使用一些第三方库,我的默认 app.config 文件正在生成类似的代码

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

这是因为我的解决方案引用了一个库的不同版本,因此它需要告诉每个人:“嘿,如果您要查找此库的任何 oldVersion,只需使用 新版本”。没关系。

问题是我想定义一个单独的配置文件“test.exe.config”,其中有一些设置并删除自动生成的设置。

为了告诉我的应用程序有关新配置文件的信息,我正在使用类似的代码

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");

这(几乎)完美地工作了。我在那里写了“几乎”,因为尽管 <appSettings>部分被正确读取,<runtime>我的自定义配置文件中没有查看该部分,但应用程序在默认配置文件中查找它,这是一个问题,因为我希望稍后能够删除该部分。

那么,我如何告诉我的应用程序也读取 <runtime>我的自定义配置文件中的信息?

<小时/>

如何重现问题

重现我的问题的简单示例如下:

使用单个类创建一个名为 ClassLibrary2 (.Net Framework v4.6) 的库,如下所示

using Newtonsoft.Json.Linq;
using System;

namespace ClassLibrary2
{
public class Class1
{
public Class1()
{
var json = new JObject();
json.Add("Succeed?", true);

Reash = json.ToString();
}

public String Reash { get; set; }
}
}

请注意对 Newtonsoft 软件包的引用。库中安装的是v10.0.2

现在创建一个名为 ConsoleApp2 (.Net Framework v4.6) 的控制台应用程序,其中包含一个名为 Program 的类,其内容如下:

using System;
using System.Configuration;

namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");

var AppSettings = ConfigurationManager.AppSettings;

Console.WriteLine($"{AppSettings.Count} settings found");
Console.WriteLine($"Calling ClassLibrary2: {Environment.NewLine}{new ClassLibrary2.Class1().Reash}");
Console.ReadLine();

}
}
}

此应用程序还应该安装Newtonsoft,但版本不同v12.0.3

在 Debug模式下构建应用程序。然后,在文件夹 ConsoleApp2/ConsoleApp2/bin/Debug 中创建一个名为 test.exe.config 的文件,其中包含以下内容

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<appSettings>
<add key="A" value="1"/>
<add key="B" value="1"/>
<add key="C" value="1"/>
</appSettings>
</configuration>

并注意,在同一个Debug文件夹中还有默认配置文件ConsoleApp2.exe.config,其内容如下

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

如果此时运行应用程序,它将毫无问题地进行编译,并且您应该看到类似的控制台

enter image description here

请注意,(3) 设置是从我的自定义配置文件中正确读取的。到目前为止一切顺利...

现在将默认配置文件重命名为 _ConsoleApp2.exe.config 并再次运行应用程序。您现在应该得到一个FileLoadException

enter image description here

再说一次,我怎样才能告诉我的应用程序阅读 <runtime>我的自定义配置文件中的信息?

<小时/>

基本原理

我寻找这个问题的答案的原因如下:

当我们发布应用程序时,我们将所有 .exe 和 .dll 文件放在一个文件夹中,并将自定义配置文件(带有设置等)放在另一个文件夹中,我们的客户在其中有类似的文件。

在包含 .exe 和 .dll 文件的文件夹中,我们尽量保留尽可能少的文件,因此我被要求找到一种方法来删除该 ConsoleApp2.exe.config(如果可能)。现在,由于上述绑定(bind)已写入该配置文件中,我只是尝试将该信息移动到我们的自定义配置文件中...但到目前为止我未能实现:始终尝试从该 读取绑定(bind)重定向ConsoleApp2.exe.config,所以一旦我删除它,我就会遇到异常...

最佳答案

您可能正在寻找配置转换:

背后的想法是,您在 Visual Studio 中创建多个配置,例如配置管理器中的调试、发布、生产、测试​​...以及默认配置文件以及所谓的变换。

请注意,您可以在配置管理器中创建任意数量的配置。要添加新配置,请单击解决方案配置(下拉列表显示“调试”或“发布”),然后选择“配置管理器...”。打开它,您会看到所有当前现有配置的列表。下拉组合框“事件解决方案配置”并选择“<New...>”以添加更多。

这些转换指定了特定配置与默认配置不同的原因 - 因此您无需重复在默认配置中已指定的内容,而只需提及差异,例如示例:

<configuration>
<appSettings>
<add key="ClientSessionTimeout" value="100"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
</configuration>

通过其键 ClientSessionTimeout 查找相关设置并将其值设置为 100通过替换配置文件中的原始值(这就是附加转换属性 xdt:Transform="SetAttributes" xdt:Locator="Match(key)" 的含义)。您还可以指定删除现有设置(通过指定 xdt:Transform="Remove" 来代替),例如

<add key="UserIdForDebugging" xdt:Transform="Remove" xdt:Locator="Match(key)"/>

将删除仅用于调试而非发布的用户 ID(要了解有关可用选项的更多信息,请查看 here - 针对 Web.config 进行描述,但也适用于 App.config)。

除了App.Config文件,每个配置一个文件,即 App.Debug.Config用于调试,App.Release.Config用于发布等。Visual Studio 可以帮助您创建它们。

我已经在 StackOverflow here 中创建了答案和 there ,里面有详细的介绍,请看一下。

如果您在 Visual Studio 中显示它们时遇到问题,请查看 here .

<小时/>

关于您的理由:

转换通过将转换文件应用到默认配置文件来创建完整的配置文件。生成的文件被编译并与其他编译文件一起放入“bin”文件夹中。因此,如果您选择了配置“Release”,那么包括转换后的配置文件在内的所有文件都会编译到“bin\Release”中。

配置文件的命名就是exe文件的名字加上末尾的“.config”(也就是说,二进制文件夹中没有“.Release.config”,而是有一个“MySuperCoolApp.exe.config” ”创建 - 为应用程序“MySuperCoolApp.exe”)。

同样,其他配置也是如此 - 每个配置都会在“bin”内创建一个子文件夹 - 如果您使用脚本,则该子文件夹可以引用为 $(TargetDir)在构建后事件中。

关于c# - 如何告诉应用程序从我的自定义 app.config 文件而不是默认文件中读取 <runtime>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59312188/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com