尝试使用log4net作为单个文件部署用.Net 5编写的控制台应用程序。运行已部署的应用程序将引发异常。
重现步骤
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure(new FileInfo("log.config"));
var logger = log4net.LogManager.GetLogger("TestLogger");
logger.Info("Hello World!");
}
<?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-自包含true -r win-x64
dotnet publish -o。\ Publish-自包含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)
我错过了什么?
因此,我认为问题是由于.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,您需要编辑项目文件,并为文件添加此行,
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
并且<CopyToOutputDirectory>Always</CopyToOutputDirectory>
添加
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
到我在Visual Studio中的* .pubxml文件中为我解决了该问题。感谢您对IncludeAllContentForSelfExtract的提示