简体   繁体   中英

.NET 5.0 Single File Publish user.config issue

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM