@@ -128,6 +128,8 @@ public static bool LogToConsoleError
128128
129129 /// <summary>
130130 /// Gets or sets the file path of the internal log file.
131+ ///
132+ /// Supports environment variables like %APPDATA% or %LOCALAPPDATA% or %PROGRAMDATA%, and some NLog-specific variables like ${basedir}, ${processdir}, ${currentdir}.
131133 /// </summary>
132134 /// <remarks>A value of <see langword="null" /> value disables internal logging to a file.</remarks>
133135 public static string ? LogFile
@@ -460,23 +462,22 @@ private static string ExpandFilePathVariables(string internalLogFile)
460462 {
461463 try
462464 {
463- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${currentdir}" , out var currentDirToken ) )
465+ if ( internalLogFile . IndexOf ( '%' ) >= 0 )
466+ internalLogFile = Environment . ExpandEnvironmentVariables ( internalLogFile ) ; // Support environment variables like %APPDATA% or %LOCALAPPDATA% or %PROGRAMDATA%
467+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${currentdir}" , out var currentDirToken ) && currentDirToken != null )
464468 internalLogFile = internalLogFile . Replace ( currentDirToken , System . IO . Directory . GetCurrentDirectory ( ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
465- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${basedir}" , out var baseDirToken ) )
469+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${basedir}" , out var baseDirToken ) && baseDirToken != null )
466470 internalLogFile = internalLogFile . Replace ( baseDirToken , LogManager . LogFactory . CurrentAppEnvironment . AppDomainBaseDirectory + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
467- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${tempdir}" , out var tempDirToken ) )
471+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${tempdir}" , out var tempDirToken ) && tempDirToken != null )
468472 internalLogFile = internalLogFile . Replace ( tempDirToken , LogManager . LogFactory . CurrentAppEnvironment . UserTempFilePath + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
469- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${processdir}" , out var processDirToken ) )
473+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${processdir}" , out var processDirToken ) && processDirToken != null )
470474 internalLogFile = internalLogFile . Replace ( processDirToken , System . IO . Path . GetDirectoryName ( LogManager . LogFactory . CurrentAppEnvironment . CurrentProcessFilePath ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
471- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${commonApplicationDataDir}" , out var commonAppDataDirToken ) )
475+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${commonApplicationDataDir}" , out var commonAppDataDirToken ) && commonAppDataDirToken != null )
472476 internalLogFile = internalLogFile . Replace ( commonAppDataDirToken , NLog . LayoutRenderers . SpecialFolderLayoutRenderer . GetFolderPath ( Environment . SpecialFolder . CommonApplicationData ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
473- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${userApplicationDataDir}" , out var appDataDirToken ) )
477+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${userApplicationDataDir}" , out var appDataDirToken ) && appDataDirToken != null )
474478 internalLogFile = internalLogFile . Replace ( appDataDirToken , NLog . LayoutRenderers . SpecialFolderLayoutRenderer . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
475- if ( ContainsSubStringIgnoreCase ( internalLogFile , "${userLocalApplicationDataDir}" , out var localapplicationdatadir ) )
476- internalLogFile = internalLogFile . Replace ( localapplicationdatadir , NLog . LayoutRenderers . SpecialFolderLayoutRenderer . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
477- if ( internalLogFile . IndexOf ( '%' ) >= 0 )
478- internalLogFile = Environment . ExpandEnvironmentVariables ( internalLogFile ) ;
479-
479+ if ( ContainsSubStringIgnoreCase ( internalLogFile , "${userLocalApplicationDataDir}" , out var localapplicationdataToken ) && localapplicationdataToken != null )
480+ internalLogFile = internalLogFile . Replace ( localapplicationdataToken , NLog . LayoutRenderers . SpecialFolderLayoutRenderer . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) + System . IO . Path . DirectorySeparatorChar . ToString ( ) ) ;
480481 if ( ! string . IsNullOrEmpty ( internalLogFile ) && internalLogFile . IndexOf ( '.' ) >= 0 )
481482 internalLogFile = AppEnvironmentWrapper . FixFilePathWithLongUNC ( internalLogFile ) ;
482483
@@ -488,12 +489,7 @@ private static string ExpandFilePathVariables(string internalLogFile)
488489 }
489490 }
490491
491- private static bool ContainsSubStringIgnoreCase ( string haystack , string needle ,
492- #if NETSTANDARD2_1_OR_GREATER || NET
493- [ System . Diagnostics . CodeAnalysis . NotNullWhen ( true ) ]
494- #endif
495- out string ? result
496- )
492+ private static bool ContainsSubStringIgnoreCase ( string haystack , string needle , out string ? result )
497493 {
498494 int needlePos = haystack . IndexOf ( needle , StringComparison . OrdinalIgnoreCase ) ;
499495 result = needlePos >= 0 ? haystack . Substring ( needlePos , needle . Length ) : null ;
0 commit comments