Visual Studio 迁移到.Net Core 5 -生成的.config文件的名称已更改

new9mtju  于 2023-01-14  发布在  .NET
关注(0)|答案(2)|浏览(154)

我正在将我们的一个Visual Studio解决方案迁移到.Net Core 5。它有两个项目:Visual Basic中的WinForms应用程序(旧版)和C#中的类库。
我注意到为WinForms应用程序生成的.config文件的名称与以前的版本不同:它以前是{WinForms应用程序名称}.exe.config,现在是{WinForms应用程序名称}. dll. config。
我还没能找到关于这个名称更改的文档。
我担心的是我们的版本更新过程。在我们软件的每个新版本中,我们都会向IT运营人员提供.exe和.dll文件,他们会设置这些文件以供使用。如果.config文件中有更改,我们也会提供一个注解,告诉他们要添加、删除或更新哪些节点。
现在,我不知道这个可执行文件是否能很好地与旧名称格式的配置文件一起工作。所以我做了一些实验。首先,我更改了.dll.config文件中一个键的值,并直接启动.exe。通常情况下,这些更改会被考虑在内。然后,我再次将.dll.config文件重命名为.exe.config,并重新启动. exe。这次,应用程序使用初始值。即使我再次更改.exe.config文件。
我也尝试过手动重命名配置文件:简单地(并且可预测地)构建解决方案创建了新的.dll.config文件。
1.有关于这个的文件吗?
1.有没有办法撤销这一名称更改,让我们的IT操作人员不必对此感到疑惑?(他们已经够忙碌的了。)

9avjhtql

9avjhtql1#

这种变化的原因与我在那里的回答有关:库的文件格式是否仅为DLL文件?
NET核心应用程序的.exe文件只是一个存根加载程序。实际代码在.dll文件中。注意,对于应用程序项目,您现在有application.dllapplication.exe。我很少操作配置文件,所以我不太确定那里的条目,但如果它与.dll.config一起工作,然后使用它。无论如何,你必须告诉你的IT关于这个变化,因为可能还有其他破坏性的变化(他们可能还需要安装新的框架,等等)。
请确保您的C#库和应用程序没有使用相同的名称。这在以前的.NET框架中是有效的,但在.NET核心中将是一个问题。

ffvjumwh

ffvjumwh2#

有一个相关的答案here,其中@DeepSpace101提到:
还有,app.config在运行时的位置与.net framework中的不同,而不是“projectName.exe.config”,现在在.net core中是“projectName.dll.config”。
我最近在将一些WinForms应用程序从.NET Framework 4. 8迁移到.NET 7后遇到了这个问题。我注意到,即使.exe.config文件包含显式覆盖值,我所有的设置都返回默认值。我首先尝试查看应用程序基于this answer加载的是哪个配置文件,但是AppDomain.CurrentDomain.SetupInformation.ConfigurationFile在.NET“核心”中不可用。然后基于another answer,我检查了ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath,它确认应用程序是从projectName.dll.config而不是projectName. exe. config加载的。
幸运的是,我找到了一个基于this answer和这个GitHub问题的很好的解决方案。ConfigurationManager支持AppDomain.SetData的APP_CONFIG_FILE键来覆盖.config文件,只要它在任何ConfigurationManager代码执行之前被调用。我已经做了一个实用函数,我可以从我所有的WinForms.exe中调用它作为他们程序的Main()入口点的第一行:

/// <summary>
/// Overrides .NET's Core's ConfigurationManager to use AppName.exe.config instead 
/// of AppName.dll.config.
/// </summary>
/// <param name="exeConfigName">An optional name of an .exe.config file to use.
/// If null, then the entry assembly's file name without extension is used with
/// ".exe.config" appended.</param>
/// <remarks>
/// For this to take effect, this method must be called before any application code
/// pulls a configuration value.
/// </remarks>
public static void UseExeConfig(string? exeConfigName = null)
{
    // .NET Framework and Core support using APP_CONFIG_FILE to override which .config
    // file an app reads its settings from.
    // https://github.com/dotnet/runtime/pull/56748#discussion_r682287640
    //
    // Note 1: This .exe.config override only affects some sections of the file. Anything
    // read by the CLR host before the app starts (e.g., settings in the <runtime> section
    // like <gcServer>) will only be read from the app's default config file.
    // https://stackoverflow.com/questions/1838619/relocating-app-config-file-to-a-custom-path/12708388#12708388
    // However, that's only an issue for .NET Framework since .NET Core reads its CLR host
    // runtime settings from other places. https://learn.microsoft.com/en-us/dotnet/core/runtime-config/
    //
    // Note 2: We have to be careful to only reference base CLR methods here and not use 
    // anything from referenced assemblies. If we run any code that pulls a configuration
    // setting before we change APP_CONFIG_FILE, then our change will be ignored.
    string? entryAssemblyLocation = Assembly.GetEntryAssembly()?.Location;
    if (entryAssemblyLocation != null)
    {
        string entryAssemblyFile = Path.GetFileName(entryAssemblyLocation);
        string entryConfigName = entryAssemblyFile + ".config";
        exeConfigName ??= Path.GetFileNameWithoutExtension(entryAssemblyFile) + ".exe.config";
        if (!entryConfigName.Equals(exeConfigName, StringComparison.OrdinalIgnoreCase))
        {
            string basePath = Path.GetDirectoryName(entryAssemblyLocation) ?? string.Empty;
            string exeConfigFilePath = Path.Combine(basePath, exeConfigName);
            AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", exeConfigFilePath);
        }
    }
}

此技术还可用于强制多个应用程序共享单个.config文件。例如,如果您希望Service.exe和Worker.exe都查看Service.exe.config,则从它们的每个Main方法调用UseExeConfig("Service.exe.config")。这样,IT/支持人员只需在一个位置配置连接字符串。

相关问题