diff --git a/src/Build/Logging/BinaryLogger/BinaryLogger.cs b/src/Build/Logging/BinaryLogger/BinaryLogger.cs
index 5cbc5c4f5e8..f68a78cc047 100644
--- a/src/Build/Logging/BinaryLogger/BinaryLogger.cs
+++ b/src/Build/Logging/BinaryLogger/BinaryLogger.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Microsoft.Build.Experimental.BuildCheck.Infrastructure.EditorConfig;
@@ -137,6 +138,17 @@ public enum ProjectImportsCollectionMode
internal string FilePath { get; private set; }
+ ///
+ /// Gets or sets additional output file paths. When set, the binlog will be copied to all these paths
+ /// after the build completes. The primary FilePath will be used as the temporary write location.
+ ///
+ ///
+ /// This property is intended for internal use by MSBuild command-line processing.
+ /// It should not be set by external code or logger implementations.
+ /// Use multiple logger instances with different Parameters instead.
+ ///
+ public List AdditionalFilePaths { get; set; }
+
/// Gets or sets the verbosity level.
///
/// The binary logger Verbosity is always maximum (Diagnostic). It tries to capture as much
@@ -355,6 +367,38 @@ public void Shutdown()
stream.Dispose();
stream = null;
}
+
+ // Copy the binlog file to additional destinations if specified
+ if (AdditionalFilePaths != null && AdditionalFilePaths.Count > 0)
+ {
+ foreach (var additionalPath in AdditionalFilePaths)
+ {
+ try
+ {
+ string directory = Path.GetDirectoryName(additionalPath);
+ if (!string.IsNullOrEmpty(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+ File.Copy(FilePath, additionalPath, overwrite: true);
+ }
+ catch (Exception ex)
+ {
+ // Log the error but don't fail the build
+ string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(
+ out string errorCode,
+ out string helpKeyword,
+ "ErrorCopyingBinaryLog",
+ FilePath,
+ additionalPath,
+ ex.Message);
+
+ // Note: We can't write this error to the binlog itself since the stream is already closed
+ // The error will be logged to the console or other active loggers
+ Console.Error.WriteLine(message);
+ }
+ }
+ }
}
private void RawEvents_LogDataSliceReceived(BinaryLogRecordKind recordKind, Stream stream)
@@ -514,5 +558,108 @@ private string GetUniqueStamp()
private static string ExpandPathParameter(string parameters)
=> $"{DateTime.UtcNow.ToString("yyyyMMdd-HHmmss")}--{EnvironmentUtilities.CurrentProcessId}--{StringUtils.GenerateRandomString(6)}";
+
+ ///
+ /// Extracts the file path from binary logger parameters string.
+ /// This is a helper method for processing multiple binlog parameters.
+ ///
+ /// The parameters string (e.g., "output.binlog" or "output.binlog;ProjectImports=None")
+ /// The resolved file path, or "msbuild.binlog" if no path is specified
+ public static string ExtractFilePathFromParameters(string parameters)
+ {
+ if (string.IsNullOrEmpty(parameters))
+ {
+ return Path.GetFullPath("msbuild.binlog");
+ }
+
+ var paramParts = parameters.Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries);
+ string filePath = null;
+
+ foreach (var parameter in paramParts)
+ {
+ if (TryInterpretPathParameterStatic(parameter, out string extractedPath))
+ {
+ filePath = extractedPath;
+ break;
+ }
+ }
+
+ if (filePath == null)
+ {
+ filePath = "msbuild.binlog";
+ }
+
+ try
+ {
+ return Path.GetFullPath(filePath);
+ }
+ catch
+ {
+ // If path resolution fails, return the original path
+ return filePath;
+ }
+ }
+
+ private static bool TryInterpretPathParameterStatic(string parameter, out string filePath)
+ {
+ bool hasPathPrefix = parameter.StartsWith("LogFile=", StringComparison.OrdinalIgnoreCase);
+
+ if (hasPathPrefix)
+ {
+ parameter = parameter.Substring("LogFile=".Length);
+ }
+
+ parameter = parameter.Trim('"');
+
+ bool isWildcard = ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_12) && parameter.Contains("{}");
+ bool hasProperExtension = parameter.EndsWith(".binlog", StringComparison.OrdinalIgnoreCase);
+ filePath = parameter;
+
+ if (!isWildcard)
+ {
+ return hasProperExtension;
+ }
+
+ filePath = parameter.Replace("{}", ExpandPathParameter(string.Empty), StringComparison.Ordinal);
+
+ if (!hasProperExtension)
+ {
+ filePath += ".binlog";
+ }
+ return true;
+ }
+
+ ///
+ /// Extracts the non-file-path parameters from binary logger parameters string.
+ /// This is used to compare configurations between multiple binlog parameters.
+ ///
+ /// The parameters string (e.g., "output.binlog;ProjectImports=None")
+ /// A normalized string of non-path parameters, or empty string if only path parameters
+ public static string ExtractNonPathParameters(string parameters)
+ {
+ if (string.IsNullOrEmpty(parameters))
+ {
+ return string.Empty;
+ }
+
+ var paramParts = parameters.Split(MSBuildConstants.SemicolonChar, StringSplitOptions.RemoveEmptyEntries);
+ var nonPathParams = new List();
+
+ foreach (var parameter in paramParts)
+ {
+ // Skip file path parameters
+ if (TryInterpretPathParameterStatic(parameter, out _))
+ {
+ continue;
+ }
+
+ // This is a configuration parameter (like ProjectImports=None, OmitInitialInfo, etc.)
+ nonPathParams.Add(parameter);
+ }
+
+ // Sort for consistent comparison
+ nonPathParams.Sort(StringComparer.OrdinalIgnoreCase);
+ return string.Join(";", nonPathParams);
+ }
}
}
diff --git a/src/Build/Resources/Strings.resx b/src/Build/Resources/Strings.resx
index ba039159363..23cb9a697a3 100644
--- a/src/Build/Resources/Strings.resx
+++ b/src/Build/Resources/Strings.resx
@@ -2449,10 +2449,14 @@ Utilization: {0} Average Utilization: {1:###.0}
The directory does not exist: {0}. .NET Runtime Task Host could not be instantiated. See https://aka.ms/nettaskhost for details on how to resolve this error.
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+
diff --git a/src/Build/Resources/xlf/Strings.cs.xlf b/src/Build/Resources/xlf/Strings.cs.xlf
index 25c7cd53ecf..dc0fd9cd435 100644
--- a/src/Build/Resources/xlf/Strings.cs.xlf
+++ b/src/Build/Resources/xlf/Strings.cs.xlf
@@ -484,6 +484,11 @@
Číst proměnnou prostředí {0}
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: Při čtení vstupních souborů mezipaměti pro výsledky z cesty {0} byla zjištěna chyba: {1}
diff --git a/src/Build/Resources/xlf/Strings.de.xlf b/src/Build/Resources/xlf/Strings.de.xlf
index 772ecb9a0b1..4a9c5defb7c 100644
--- a/src/Build/Resources/xlf/Strings.de.xlf
+++ b/src/Build/Resources/xlf/Strings.de.xlf
@@ -484,6 +484,11 @@
Umgebungsvariable "{0}" lesen
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: Beim Lesen der Cachedateien für Eingabeergebnisse aus dem Pfad "{0}" wurde ein Fehler festgestellt: {1}
diff --git a/src/Build/Resources/xlf/Strings.es.xlf b/src/Build/Resources/xlf/Strings.es.xlf
index afc0dee6a76..baee8d14d67 100644
--- a/src/Build/Resources/xlf/Strings.es.xlf
+++ b/src/Build/Resources/xlf/Strings.es.xlf
@@ -484,6 +484,11 @@
Leer la variable de entorno "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: Error al leer los archivos de caché de resultados de entrada en la ruta de acceso "{0}": {1}
diff --git a/src/Build/Resources/xlf/Strings.fr.xlf b/src/Build/Resources/xlf/Strings.fr.xlf
index 42030382266..9411affc2b0 100644
--- a/src/Build/Resources/xlf/Strings.fr.xlf
+++ b/src/Build/Resources/xlf/Strings.fr.xlf
@@ -484,6 +484,11 @@
Lire la variable d'environnement "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: La lecture des fichiers cache des résultats d'entrée à partir du chemin "{0}" a rencontré une erreur : {1}
diff --git a/src/Build/Resources/xlf/Strings.it.xlf b/src/Build/Resources/xlf/Strings.it.xlf
index 8d4a71db6cc..cbddcc65063 100644
--- a/src/Build/Resources/xlf/Strings.it.xlf
+++ b/src/Build/Resources/xlf/Strings.it.xlf
@@ -484,6 +484,11 @@
Legge la variabile di ambiente "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: durante la lettura dei file della cache dei risultati di input dal percorso "{0}" è stato rilevato un errore: {1}
diff --git a/src/Build/Resources/xlf/Strings.ja.xlf b/src/Build/Resources/xlf/Strings.ja.xlf
index c2d1232e5c3..d084d211181 100644
--- a/src/Build/Resources/xlf/Strings.ja.xlf
+++ b/src/Build/Resources/xlf/Strings.ja.xlf
@@ -484,6 +484,11 @@
環境変数 "{0}" の読み取り
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: パス "{0}" から入力結果キャッシュ ファイルを読み取る処理でエラーが発生しました: {1}
diff --git a/src/Build/Resources/xlf/Strings.ko.xlf b/src/Build/Resources/xlf/Strings.ko.xlf
index 0ba356c02dd..52fba07a9da 100644
--- a/src/Build/Resources/xlf/Strings.ko.xlf
+++ b/src/Build/Resources/xlf/Strings.ko.xlf
@@ -484,6 +484,11 @@
환경 변수 "{0}" 읽기
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: "{0}" 경로에서 입력 결과 캐시 파일을 읽는 중 오류가 발생했습니다. {1}
diff --git a/src/Build/Resources/xlf/Strings.pl.xlf b/src/Build/Resources/xlf/Strings.pl.xlf
index db557e607b7..074ed4e5576 100644
--- a/src/Build/Resources/xlf/Strings.pl.xlf
+++ b/src/Build/Resources/xlf/Strings.pl.xlf
@@ -484,6 +484,11 @@
Odczytaj zmienną środowiskową „{0}”
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: Podczas odczytywania plików wejściowej pamięci podręcznej wyników ze ścieżki „{0}” wystąpił błąd: {1}
diff --git a/src/Build/Resources/xlf/Strings.pt-BR.xlf b/src/Build/Resources/xlf/Strings.pt-BR.xlf
index 0fdc6c3a661..fa2c8439844 100644
--- a/src/Build/Resources/xlf/Strings.pt-BR.xlf
+++ b/src/Build/Resources/xlf/Strings.pt-BR.xlf
@@ -484,6 +484,11 @@
Ler a variável de ambiente "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: a leitura dos arquivos de cache do resultado de entrada do caminho "{0}" encontrou um erro: {1}
diff --git a/src/Build/Resources/xlf/Strings.ru.xlf b/src/Build/Resources/xlf/Strings.ru.xlf
index 65fae70a6b4..5cc22d1a111 100644
--- a/src/Build/Resources/xlf/Strings.ru.xlf
+++ b/src/Build/Resources/xlf/Strings.ru.xlf
@@ -484,6 +484,11 @@
Чтение переменной среды "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: произошла ошибка при чтении входных файлов кэша результатов из пути "{0}": {1}
diff --git a/src/Build/Resources/xlf/Strings.tr.xlf b/src/Build/Resources/xlf/Strings.tr.xlf
index d7a5b73f457..f821c46de29 100644
--- a/src/Build/Resources/xlf/Strings.tr.xlf
+++ b/src/Build/Resources/xlf/Strings.tr.xlf
@@ -484,6 +484,11 @@
"{0}" ortam değişkenini oku
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: "{0}" yolundan giriş sonucu önbellek dosyaları okunurken bir hatayla karşılaşıldı: {1}
diff --git a/src/Build/Resources/xlf/Strings.zh-Hans.xlf b/src/Build/Resources/xlf/Strings.zh-Hans.xlf
index 38c29a92a28..34ccc3065ae 100644
--- a/src/Build/Resources/xlf/Strings.zh-Hans.xlf
+++ b/src/Build/Resources/xlf/Strings.zh-Hans.xlf
@@ -484,6 +484,11 @@
读取环境变量“{0}”
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: 从路径“{0}”读取输入结果缓存文件时遇到错误: {1}
diff --git a/src/Build/Resources/xlf/Strings.zh-Hant.xlf b/src/Build/Resources/xlf/Strings.zh-Hant.xlf
index 67c2885adde..49473355c29 100644
--- a/src/Build/Resources/xlf/Strings.zh-Hant.xlf
+++ b/src/Build/Resources/xlf/Strings.zh-Hant.xlf
@@ -484,6 +484,11 @@
讀取環境變數 "{0}"
+
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ MSB4279: Failed to copy binary log from "{0}" to "{1}". {2}
+ {StrBegin="MSB4279: "}UE: This is shown when the Binary Logger fails to copy the log file to one of the specified output locations.
+ MSB4256: Reading input result cache files from path "{0}" encountered an error: {1}MSB4256: 從路徑 "{0}" 讀取輸入結果快取檔案發生錯誤: {1}
diff --git a/src/MSBuild.UnitTests/XMake_Tests.cs b/src/MSBuild.UnitTests/XMake_Tests.cs
index f5de4715ccb..95efe235d31 100644
--- a/src/MSBuild.UnitTests/XMake_Tests.cs
+++ b/src/MSBuild.UnitTests/XMake_Tests.cs
@@ -2655,6 +2655,116 @@ public void BinaryLogContainsImportedFiles()
archive.Entries.ShouldContain(e => e.FullName.EndsWith(".proj", StringComparison.OrdinalIgnoreCase), 2);
}
+ [Fact]
+ public void MultipleBinaryLogsCreatesMultipleFiles()
+ {
+ var testProject = _env.CreateFile("TestProject.proj", @"
+
+
+
+
+
+ ");
+
+ string binLogLocation = _env.DefaultTestDirectory.Path;
+ string binLog1 = Path.Combine(binLogLocation, "1.binlog");
+ string binLog2 = Path.Combine(binLogLocation, "2.binlog");
+ string binLog3 = Path.Combine(binLogLocation, "3.binlog");
+
+ string output = RunnerUtilities.ExecMSBuild($"\"{testProject.Path}\" \"/bl:{binLog1}\" \"/bl:{binLog2}\" \"/bl:{binLog3}\"", out var success, _output);
+
+ success.ShouldBeTrue(output);
+
+ // Verify all three binlog files exist
+ File.Exists(binLog1).ShouldBeTrue("First binlog file should exist");
+ File.Exists(binLog2).ShouldBeTrue("Second binlog file should exist");
+ File.Exists(binLog3).ShouldBeTrue("Third binlog file should exist");
+
+ // Verify all files have content (are not empty)
+ new FileInfo(binLog1).Length.ShouldBeGreaterThan(0, "First binlog should not be empty");
+ new FileInfo(binLog2).Length.ShouldBeGreaterThan(0, "Second binlog should not be empty");
+ new FileInfo(binLog3).Length.ShouldBeGreaterThan(0, "Third binlog should not be empty");
+
+ // Verify all files are identical (have the same content)
+ byte[] file1Bytes = File.ReadAllBytes(binLog1);
+ byte[] file2Bytes = File.ReadAllBytes(binLog2);
+ byte[] file3Bytes = File.ReadAllBytes(binLog3);
+
+ file1Bytes.SequenceEqual(file2Bytes).ShouldBeTrue("First and second binlog should be identical");
+ file1Bytes.SequenceEqual(file3Bytes).ShouldBeTrue("First and third binlog should be identical");
+ }
+
+ [Fact]
+ public void MultipleBinaryLogsWithDuplicatesCreateDistinctFiles()
+ {
+ var testProject = _env.CreateFile("TestProject.proj", @"
+
+
+
+
+
+ ");
+
+ string binLogLocation = _env.DefaultTestDirectory.Path;
+ string binLog1 = Path.Combine(binLogLocation, "1.binlog");
+ string binLog2 = Path.Combine(binLogLocation, "2.binlog");
+
+ // Specify binLog1 twice - should only create two distinct files
+ string output = RunnerUtilities.ExecMSBuild($"\"{testProject.Path}\" \"/bl:{binLog1}\" \"/bl:{binLog2}\" \"/bl:{binLog1}\"", out var success, _output);
+
+ success.ShouldBeTrue(output);
+
+ // Verify both binlog files exist
+ File.Exists(binLog1).ShouldBeTrue("First binlog file should exist");
+ File.Exists(binLog2).ShouldBeTrue("Second binlog file should exist");
+
+ // Verify both files are identical
+ byte[] file1Bytes = File.ReadAllBytes(binLog1);
+ byte[] file2Bytes = File.ReadAllBytes(binLog2);
+
+ file1Bytes.SequenceEqual(file2Bytes).ShouldBeTrue("Binlog files should be identical");
+ }
+
+ [Fact]
+ public void MultipleBinaryLogsWithDifferentConfigurationsCreatesSeparateLoggers()
+ {
+ var testProject = _env.CreateFile("TestProject.proj", @"
+
+
+
+
+
+
+ ");
+
+ _env.CreateFile("Imported.proj", @"
+
+
+ Value
+
+
+ ");
+
+ string binLogLocation = _env.DefaultTestDirectory.Path;
+ string binLog1 = Path.Combine(binLogLocation, "with-imports.binlog");
+ string binLog2 = Path.Combine(binLogLocation, "no-imports.binlog");
+
+ // One with default imports, one with ProjectImports=None
+ string output = RunnerUtilities.ExecMSBuild($"\"{testProject.Path}\" \"/bl:{binLog1}\" \"/bl:{binLog2};ProjectImports=None\"", out var success, _output);
+
+ success.ShouldBeTrue(output);
+
+ // Verify both binlog files exist
+ File.Exists(binLog1).ShouldBeTrue("First binlog file should exist");
+ File.Exists(binLog2).ShouldBeTrue("Second binlog file should exist");
+
+ // Verify files are different sizes (one has imports embedded, one doesn't)
+ long size1 = new FileInfo(binLog1).Length;
+ long size2 = new FileInfo(binLog2).Length;
+
+ size1.ShouldBeGreaterThan(size2, "Binlog with imports should be larger than one without");
+ }
+
[Theory]
[InlineData("-warnaserror", "", "", false)]
[InlineData("-warnaserror -warnnotaserror:FOR123", "", "", true)]
diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs
index e5e12b80ae2..8c9fc96c16a 100644
--- a/src/MSBuild/XMake.cs
+++ b/src/MSBuild/XMake.cs
@@ -3949,16 +3949,75 @@ private static void ProcessBinaryLogger(string[] binaryLoggerParameters, List(StringComparer.OrdinalIgnoreCase);
+ var distinctParameterSets = new List();
+
+ // Check if all parameter sets have the same non-path configuration
+ for (int i = 0; i < binaryLoggerParameters.Length; i++)
+ {
+ string currentParams = binaryLoggerParameters[i];
+ string currentNonPathParams = BinaryLogger.ExtractNonPathParameters(currentParams);
+ string currentFilePath = BinaryLogger.ExtractFilePathFromParameters(currentParams);
+
+ // Check if this is a duplicate file path
+ if (distinctFilePaths.Add(currentFilePath))
+ {
+ // Only add if configuration matches the primary
+ if (string.Equals(primaryNonPathParams, currentNonPathParams, StringComparison.OrdinalIgnoreCase))
+ {
+ distinctParameterSets.Add(currentParams);
+ }
+ else
+ {
+ allConfigurationsIdentical = false;
+ // Still add it - we'll create separate loggers below
+ distinctParameterSets.Add(currentParams);
+ }
+ }
+ }
+
+ if (allConfigurationsIdentical && distinctParameterSets.Count > 1)
+ {
+ // Optimized approach: single logger writing to one file, then copy to additional locations
+ BinaryLogger logger = new BinaryLogger { Parameters = primaryArguments };
+
+ var additionalFilePaths = new List();
+ for (int i = 1; i < distinctParameterSets.Count; i++)
+ {
+ additionalFilePaths.Add(BinaryLogger.ExtractFilePathFromParameters(distinctParameterSets[i]));
+ }
+
+ logger.AdditionalFilePaths = additionalFilePaths;
+ loggers.Add(logger);
+ }
+ else
+ {
+ // Create separate logger instances for each distinct configuration
+ foreach (string paramSet in distinctParameterSets)
+ {
+ BinaryLogger logger = new BinaryLogger { Parameters = paramSet };
+ loggers.Add(logger);
+ }
+ }
}
///