【问题标题】:Deploy as single-file in .net5 with log4net throws exception for config-file在 .net5 中部署为单个文件,log4net 为配置文件抛出异常
【发布时间】:2020-11-20 12:02:29
【问题描述】:

尝试部署一个用 .Net 5 编写的控制台应用程序,并将 log4net 作为单个文件。 运行已部署的应用程序会引发异常。

复制步骤

  • dotnet new console --name TestConsole --language C#(确保 .net 5.0)
  • 安装包 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(始终复制)
<?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>
  • 发布(没有单个文件)= 工作(运行控制台应用程序时)

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

  • 发布(没有单个文件)= 抛出异常(运行控制台应用程序时)

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

抛出异常:

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)

我错过了什么?

【问题讨论】:

    标签: c# deployment log4net .net-5 single-file


    【解决方案1】:

    所以我认为这个问题是由于 .NET 5 的变化造成的。我还假设 log4net 需要更新才能使用新的单一文件格式。

    这里有一个关于 .NET 5 处理单个文件的方式与 3.1 不同的讨论。

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

    在 3.1 中,从技术上讲,单个可执行文件会被解压缩并从 temp 运行(根据我的经验,如果这些文件未在项目文件中设置为包含在单个文件之外,这可能会导致本地引用文件出现问题)。在 .NET 5 中,他们试图转移到程序集在内存中执行时保留在同一目录中的情况。但是,很明显,这会导致您在 log4net 中发现的其他问题。

    上面的这个链接让我得到了答案:

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

    /p:IncludeAllContentForSelfExtract=true 强制 .NET 5 单个文件的行为与 3.1 完全相同,这对我有用。

    我将在接下来的几个月中继续尝试,希望 log4net .NET 5 兼容性开始使用新格式。但至少这面旗帜让我前进了。

    【讨论】:

    • 它成功了,但是log.config没有发布,我不得不手动复制它。
    • @McClint 你需要编辑你的项目文件,并为你的文件添加这一行&lt;ExcludeFromSingleFile&gt;true&lt;/ExcludeFromSingleFile&gt;&lt;CopyToOutputDirectory&gt;Always&lt;/CopyToOutputDirectory&gt;
    • 在 Visual Studio 中将 &lt;IncludeAllContentForSelfExtract&gt;true&lt;/IncludeAllContentForSelfExtract&gt; 添加到我的 *.pubxml 文件中为我解决了这个问题。感谢您对 IncludeAllContentForSelfExtract 的提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2019-08-15
    • 1970-01-01
    • 2018-09-13
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多