There's a related answer here where @DeepSpace101 mentions:
Also, the location of app.config at runtime is different than what was in .net framework, instead of "projectName.exe.config". It is now "projectName.dll.config" in .net core.
I recently ran into this problem after migrating some WinForms apps from .NET Framework 4.8 to .NET 7. I noticed that all my settings were returning default values even when the .exe.config file contained an explicit override value. I first tried to see which config file the app was loading based on this answer, but AppDomain.CurrentDomain.SetupInformation.ConfigurationFile isn't available in .NET "Core". Then based on another answer, I checked ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath, which confirmed the app was loading from projectName.dll.config instead of projectName.exe.config.
Fortunately, I found a good workaround based on this answer and this GitHub issue. ConfigurationManager supports an APP_CONFIG_FILE key for AppDomain.SetData to override the .config file as long as it is called before any ConfigurationManager code is executed. I've made a utility function that I call from all of my WinForms .exes as the first line in their Program's Main() entry point:
/// <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);
        }
    }
}
This technique can also be used to force multiple applications to share a single .config file. For example, if you want Service.exe and Worker.exe to both look at Service.exe.config, then call UseExeConfig("Service.exe.config") from each of their Main methods. That allows IT/Support to only have to configure connection strings in one place.