Deploy as single-file in .net5 with log4net throws exception for config-file

你说的曾经没有我的故事 提交于 2021-01-27 07:22:32

问题


Trying to deploy a console-application written in .Net 5 with log4net as a single-file. Running deployed application throws exception.

Steps to reproduce

  • dotnet new console --name TestConsole --language C# (make sure .net 5.0)
  • Install-Package log4net
  • Program.cs
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure(new FileInfo("log.config"));
var logger = log4net.LogManager.GetLogger("TestLogger");
logger.Info("Hello World!");
}
  • log.config (copy always)
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <logger name="TestLogger">
    <level value="ALL" />
    <appender-ref ref="console" />
  </logger>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%level - %message%newline" />
    </layout>
  </appender>
</log4net>
  • publish (no single file) = works (when running the console application)

dotnet publish -o .\Publish --self-contained true -r win-x64

  • publish (no single file) = throws exception (when running the console application)

dotnet publish -o .\Publish --self-contained true -r win-x64 -p:PublishSingleFile=true

excpetion thrown:

log4net:ERROR Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize
 ---> System.IO.FileNotFoundException: Cannot find file. (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.ClientConfigurationHost.get_ConfigPaths()
   at System.Configuration.ClientConfigurationHost.GetStreamName(String configPath)
   at System.Configuration.ClientConfigurationHost.get_IsAppConfigHttp()
   at System.Configuration.Internal.DelegatingConfigHost.get_IsAppConfigHttp()
   at System.Configuration.ClientConfigurationSystem..ctor()
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_AppSettings()
   at log4net.Util.SystemInfo.GetAppSetting(String key)
log4net:ERROR Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize
 ---> System.IO.FileNotFoundException: Cannot find file. (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.ClientConfigurationHost.get_ConfigPaths()
   at System.Configuration.ClientConfigurationHost.GetStreamName(String configPath)
   at System.Configuration.ClientConfigurationHost.get_IsAppConfigHttp()
   at System.Configuration.Internal.DelegatingConfigHost.get_IsAppConfigHttp()
   at System.Configuration.ClientConfigurationSystem..ctor()
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_AppSettings()
   at log4net.Util.SystemInfo.GetAppSetting(String key)

What have I missed?


回答1:


So I believe the issue is due to a change in .NET 5. I'm also assuming log4net will need to be updated to work with the new single file format.

There is a discussion here about how .NET 5 handles single files differently than 3.1.

https://github.com/dotnet/core/issues/5409#issuecomment-715522029

In 3.1, technically the single executable gets unzipped and ran from temp (which could cause issues with local referenced files as least in my experience, if those files were not set in the project file to be included outside the single file). In .NET 5 they were trying to move to a case where the assembly stayed in the same directory when executed into memory. However, clearly, this causes other issues as you found with log4net.

This link above put me on to the answer:

dotnet publish -r win-x64 /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true

The /p:IncludeAllContentForSelfExtract=true forces .NET 5 single files to act exactly the same as 3.1 and is what worked for me.

I'll keep trying over the next few months with the hope that log4net .NET 5 compatibility starts working with the new format. But at least this flag let me move foward.



来源:https://stackoverflow.com/questions/64929114/deploy-as-single-file-in-net5-with-log4net-throws-exception-for-config-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!