Short version
.NET Core doesn't use app.config
, you'll have to upgrade to the new config system or manually manage the files.
- Add
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
to the App1.config
file to keep it out of the bundle.
- Manually add a
MyApp.exe.config
file with the production settings and add <CopyToPublishDirectory>Always</CopyToPublishDirectory>
to have it published to the Publish
directory. Transformations won't run, so make sure it contains everything that's needed.
- Finally load the file explicitly to avoid a bug in the application's base path resolution
var hostFile=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
ConfigurationManager.OpenExeConfiguration(hostFile+".config");
To load the published file, as if it were any other file
.NET Core 3, even for Windows Forms, doesn't use app.config
. .NET Core's configuration system is described in Configuration in ASP.NET Core and despite the name, applies to every .NET Core application. It's far more powerful too, loading configuration from multiple sources, including files (even INI), databases, Azure or AWS setting stores etc.
Adding an Application Configuration File
to a new Windows Forms project, both in VS 2019 and the command line creates an App1.config
file with no special meaning as far as VS or .NET Core are concerned. Creating an AppName.exe.config
requires actually creating a new AppName.exe.config
file with the production settings.
The only way to read an Old-style .config
file is to explicitly load it with ConfigurationManager.OpenExeConfiguration. This simply loads the file and parses it. One could pass any file path, or specify a ConfigurationUserLevel which simply resolves to a file location based on the executable's base directory.
And here's where the trouble starts. There's a bug.
With Single-file executables, all files are bundled in a single host file with the .exe
extension. When that file runs for the first time, it unpacks its contents to AppData\Local\Temp\.net\
, in a new folder named for the application. By design, the application's base directory should be the host's path, where the single .exe is. Unfortunately, there's a bug and the base directory remains the location of the bundle and the .dll
that's actually run by the host.
That's why
System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None).FilePath
returns C:\Users\myUser~1\AppData\Local\Temp\.net\ConsoleApp_NetCore\nk5sdmz5.ym1\ConsoleApp_NetCore.dll.config
and I'd bet AppContext.BaseDirectory
returns C:\Users\myUser~1\AppData\Local\Temp\.net\ConsoleApp_NetCore\nk5sdmz5.ym1\
The workaround for this is to retrieve the host's path and load the settings file explicitly. This means we can now use any file name. If we keep the old convention of naming the file appname.exe.config
, we can just append .config
to the host's full path:
var hostFile=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
ConfigurationManager.OpenExeConfiguration(hostFile+".config");
This has to be done with the .NET Core File provider too.
app.config
any more. Just delete it. Put any settings inappsettings.json
or any other filer or configuration storage you may want. Evenappsettings.json
isn't a hard requirement, it's only a default name – Luthanenapp.config
any more"? Because stated like that it kinds of dismisses reality. :) What are the differences and benefits in usingappsettings.json
overapp.config
? – Tunelessappsettings.json
is only the default used by the default host builder. You can easily add other files, other sources – Luthanen.exe
bunlde is unpacked instead of the location of the.exe
. Even with appsettings.json, you have to useProcess.GetCurrentProcess().MainModule.FileName
to find the host file's (original exe's) path. With the .NET Core config system, that's just annoying and you have to pass the full path to the setting files. – LuthanenApp1.config
and noSettings.cs
file. The generated file is empty too. Are you using ConfigurationManager to read from it? In that case you may be able to use ConfigurationManager.OpenExeConfiguration with the host's path – LuthanenRight click on project > Add > New File > Config (I don't remember exact name)
and, yes, I am using ConfigurationManager, I thought that was the standard way? – Tuneless.config
files aren't used in .NET Core. You can read it only because you explicitly load it through ConfigurationManager. Given the manual steps and the trouble, it's not worth doing this any more. With the new system you'd get multiple sources, DI, logging etc out of the box, while the config files would be a lot smaller – Luthanen