Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit 9671ba1

Browse files
author
Peter Huene
committed
Write UTF-8 BOM for solution files.
Currently the solution file written out by the `sln` command uses a UTF-8 encoding without a BOM. This causes problems when the solution file contains non-ASCII code points because Visual Studio and MSBuild will not use a UTF-8 encoding when reading the solution file if the BOM is omitted. This commit causes the BOM to always be written when writing the solution files. Fixes #8184.
1 parent 3fe2916 commit 9671ba1

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/Microsoft.DotNet.Cli.Sln.Internal/SlnFile.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
using System.Collections;
3434
using System.Globalization;
3535
using System.Reflection;
36+
using System.Text;
3637
using Microsoft.DotNet.Cli.Sln.Internal.FileManipulation;
3738
using Microsoft.DotNet.Tools.Common;
3839

@@ -211,7 +212,7 @@ public void Write(string file = null)
211212
}
212213
var sw = new StringWriter();
213214
Write(sw);
214-
File.WriteAllText(FullPath, sw.ToString());
215+
File.WriteAllText(FullPath, sw.ToString(), Encoding.UTF8);
215216
}
216217

217218
private void Write(TextWriter writer)

test/dotnet-sln-add.Tests/GivenDotnetSlnAdd.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System;
1010
using System.IO;
1111
using System.Linq;
12+
using System.Text;
1213
using Xunit;
1314
using Xunit.Abstractions;
1415

@@ -554,6 +555,33 @@ public void WhenValidProjectIsPassedItGetsAdded(string testAsset)
554555
cmd.StdErr.Should().BeEmpty();
555556
}
556557

558+
[Fact]
559+
public void WhenProjectIsAddedSolutionHasUTF8BOM()
560+
{
561+
var projectDirectory = TestAssets
562+
.Get("TestAppWithEmptySln")
563+
.CreateInstance()
564+
.WithSourceFiles()
565+
.Root
566+
.FullName;
567+
568+
var projectToAdd = "Lib/Lib.csproj";
569+
var projectPath = Path.Combine("Lib", "Lib.csproj");
570+
var cmd = new DotnetCommand()
571+
.WithWorkingDirectory(projectDirectory)
572+
.ExecuteWithCapturedOutput($"sln App.sln add {projectToAdd}");
573+
cmd.Should().Pass();
574+
575+
var preamble = Encoding.UTF8.GetPreamble();
576+
preamble.Length.Should().Be(3);
577+
using (var stream = new FileStream(Path.Combine(projectDirectory, "App.sln"), FileMode.Open))
578+
{
579+
var bytes = new byte[preamble.Length];
580+
stream.Read(bytes, 0, bytes.Length);
581+
bytes.Should().BeEquivalentTo(preamble);
582+
}
583+
}
584+
557585
[Theory]
558586
[InlineData("TestAppWithSlnAndCsprojFiles")]
559587
[InlineData("TestAppWithSlnAndCsprojProjectGuidFiles")]

test/dotnet-sln-remove.Tests/GivenDotnetSlnRemove.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System;
99
using System.IO;
1010
using System.Linq;
11+
using System.Text;
1112
using Xunit;
1213

1314
namespace Microsoft.DotNet.Cli.Sln.Remove.Tests
@@ -590,6 +591,32 @@ public void WhenReferenceIsRemovedSlnBuilds()
590591
.Count().Should().Be(1, $"App {reasonString}");
591592
}
592593

594+
[Fact]
595+
public void WhenProjectIsRemovedSolutionHasUTF8BOM()
596+
{
597+
var projectDirectory = TestAssets
598+
.Get("TestAppWithSlnAndCsprojToRemove")
599+
.CreateInstance()
600+
.WithSourceFiles()
601+
.Root
602+
.FullName;
603+
604+
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
605+
var cmd = new DotnetCommand()
606+
.WithWorkingDirectory(projectDirectory)
607+
.ExecuteWithCapturedOutput($"sln App.sln remove {projectToRemove}");
608+
cmd.Should().Pass();
609+
610+
var preamble = Encoding.UTF8.GetPreamble();
611+
preamble.Length.Should().Be(3);
612+
using (var stream = new FileStream(Path.Combine(projectDirectory, "App.sln"), FileMode.Open))
613+
{
614+
var bytes = new byte[preamble.Length];
615+
stream.Read(bytes, 0, bytes.Length);
616+
bytes.Should().BeEquivalentTo(preamble);
617+
}
618+
}
619+
593620
[Fact]
594621
public void WhenFinalReferenceIsRemovedEmptySectionsAreRemoved()
595622
{

0 commit comments

Comments
 (0)