.NET 5.0 Single File Publish user.config issue

0

I'm trying to migrate WPF project from .NET Core 3.1 to .NET 5.0. My project uses default properties file (user.config) to store some app data.

Project code:


    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            try
            {
                Properties.Settings.Default.test = "Edited";
                Properties.Settings.Default.Save();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
    }

After publishing the project, I get an System.IO.FileNotFoundException (The specified file could not be found) when trying to access to Properties.Settings.Default.

---------------------------

---------------------------
System.IO.FileNotFoundException: Не удается найти указанный файл. (0x80070002)

   at System.Reflection.RuntimeModule.GetFullyQualifiedName()

   at System.Reflection.RuntimeModule.get_Name()

   at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)

   at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)

   at System.Configuration.Internal.ConfigurationManagerInternal.System.Configuration.Internal.IConfigurationManagerInternal.get_ExeProductName()

   at System.Configuration.ApplicationSettingsBase.get_Initializer()

   at System.Configuration.ApplicationSettingsBase.CreateSetting(PropertyInfo propertyInfo)

   at System.Configuration.ApplicationSettingsBase.EnsureInitialized()

   at System.Configuration.ApplicationSettingsBase.get_Properties()

   at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)

   at System.Configuration.SettingsBase.get_Item(String propertyName)

   at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)

   at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)

   at WpfApp1.Properties.Settings.get_test()

   at WpfApp1.MainWindow..ctor()
---------------------------
ОК   
---------------------------

The problem only happens when using Single File publishing.

My publish properties:

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net5.0\publish\</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <TargetFramework>net5.0-windows</TargetFramework>
    <RuntimeIdentifier>win-x86</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <PublishSingleFile>True</PublishSingleFile>
    <PublishReadyToRun>True</PublishReadyToRun>
    <PublishTrimmed>False</PublishTrimmed>
    <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
  </PropertyGroup>
</Project>

Settings class:

    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
        
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
        
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
        
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("123")]
        public string test {
            get {
                return ((string)(this["test"]));
            }
            set {
                this["test"] = value;
            }
        }
    }

Project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
  </PropertyGroup>

  <ItemGroup>
    <Compile Update="Properties\Settings.Designer.cs">
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <None Update="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
  </ItemGroup>

</Project>

Note 1: I have check %userprofile%\appdata\local folder and it not create user.config file after launching the app.

Note 2: If i put the mscorrc.dll to publish folder then all is work fine. mscorrc.dll

.net
.net-5
user.config
.net-core-publishsinglefile
asked on Stack Overflow Nov 16, 2020 by Sindeev Victor • edited Nov 16, 2020 by Sindeev Victor

1 Answer

1

Looks there's a bug in .NET 5's handling of legacy settings when single-file publishing is used. The linked Github issue shows that trying to read any setting, not just user settings, results in a System.IO.FileNotFoundException. The fix for this wasn't included in .NET 5.0.

From the issue:

A workaround is to set <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>

Long-term, you'll have to move to .NET Core's configuration system anyway. app.config and user.config are legacy technologies and issues like this are to be expected.

answered on Stack Overflow Nov 16, 2020 by Panagiotis Kanavos

User contributions licensed under CC BY-SA 3.0