From cdcb3bf767badcbf71f82932b4cbfdd67256a3f4 Mon Sep 17 00:00:00 2001 From: Chris Rudolphi <1702962+clrudolphi@users.noreply.github.com> Date: Tue, 28 Apr 2026 11:44:05 -0500 Subject: [PATCH 1/2] Modified GeneratedFileWriter to support very long file paths on Windows. --- .../GeneratedFileWriter.cs | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/Reqnroll.Tools.MsBuild.Generation/GeneratedFileWriter.cs b/Reqnroll.Tools.MsBuild.Generation/GeneratedFileWriter.cs index 11bce6031..7dac572e3 100644 --- a/Reqnroll.Tools.MsBuild.Generation/GeneratedFileWriter.cs +++ b/Reqnroll.Tools.MsBuild.Generation/GeneratedFileWriter.cs @@ -1,29 +1,30 @@ +using System; using System.IO; using System.Text; using Reqnroll.Utils; namespace Reqnroll.Tools.MsBuild.Generation; -/// -/// This class is going to be obsolete once we implement MsBuild level up-to-date checks. -/// public class GeneratedFileWriter(IReqnrollTaskLoggingHelper log) { public void WriteGeneratedFile(string outputPath, string generatedFileContent) { + var path = NormalizePath(outputPath); log.LogTaskDiagnosticMessage($"Writing data to {outputPath}"); - WriteFile(outputPath, generatedFileContent); + WriteFile(path, generatedFileContent); } public void DeleteGeneratedFile(string outputPath) { - if (!File.Exists(outputPath)) + var path = NormalizePath(outputPath); + + if (!File.Exists(path)) return; log.LogTaskDiagnosticMessage($"Deleting {outputPath}"); try { - File.Delete(outputPath); + File.Delete(path); } catch (IOException ex) { @@ -34,7 +35,7 @@ public void DeleteGeneratedFile(string outputPath) private void WriteFile(string filePath, string content) { string directoryPath = Path.GetDirectoryName(filePath); - if (directoryPath != null && !Directory.Exists(directoryPath)) + if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } @@ -42,13 +43,33 @@ private void WriteFile(string filePath, string content) WriteAllTextWithRetry(filePath, content, Encoding.UTF8); } - /// - /// When building a multi-targeted project, the build system may try to write the same file multiple times, - /// and this can cause an IOException ("The process cannot access the file because it is being used by another process."). - /// See https://github.com/reqnroll/Reqnroll/issues/197 - /// Once we move to Roslyn-based generation, this problem will go away, but for now, we use a workaround of - /// retrying the write operation a few times (the content is anyway the same). - /// + private static string NormalizePath(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path must not be null or empty.", nameof(path)); + + string fullPath = Path.GetFullPath(path); + + // Cross-platform: only apply extended syntax on Windows. + if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( + System.Runtime.InteropServices.OSPlatform.Windows)) + { + return fullPath; + } + + // Already device/extended syntax. + if (fullPath.StartsWith(@"\\?\", StringComparison.Ordinal) || + fullPath.StartsWith(@"\\.\", StringComparison.Ordinal)) + return fullPath; + + // UNC path. + if (fullPath.StartsWith(@"\\", StringComparison.Ordinal)) + return @"\\?\UNC\" + fullPath.Substring(2); + + // Drive-qualified path. + return @"\\?\" + fullPath; + } + private void WriteAllTextWithRetry(string path, string contents, Encoding encoding) { const int maxAttempts = 5; From 4d8caa1ed520e443bcd0876434b83b51fbf376a4 Mon Sep 17 00:00:00 2001 From: Chris Rudolphi <1702962+clrudolphi@users.noreply.github.com> Date: Tue, 28 Apr 2026 11:45:53 -0500 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c09d08b63..000dec9c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,9 @@ ## Improvements: ## Bug fixes: +* Fix: GenerateFeatureFileCodeBehindTask fails with misleading DirectoryNotFoundException when ndjson output path exceeds Windows MAX_PATH (260) -*Contributors of this release (in alphabetical order):* +*Contributors of this release (in alphabetical order):* @clrudolphi # v3.3.4 - 2026-03-23