Skip to content

Commit

Permalink
Include list of processes that lock file in can't write file error …
Browse files Browse the repository at this point in the history
…message

F
  • Loading branch information
tmat committed Nov 17, 2024
1 parent f6f0035 commit c0510e5
Show file tree
Hide file tree
Showing 32 changed files with 389 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3546,7 +3546,7 @@ Give the compiler some way to differentiate the methods. For example, you can gi
<value>Error opening response file '{0}'</value>
</data>
<data name="ERR_CantOpenFileWrite" xml:space="preserve">
<value>Cannot open '{0}' for writing -- '{1}'</value>
<value>Cannot open '{0}' for writing -- {1}</value>
</data>
<data name="ERR_BadBaseNumber" xml:space="preserve">
<value>Invalid image base number '{0}'</value>
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 29 additions & 1 deletion src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
using Basic.Reference.Assemblies;
using static Microsoft.CodeAnalysis.CommonDiagnosticAnalyzers;
using static Roslyn.Test.Utilities.SharedResourceHelpers;
using System.Diagnostics;

namespace Microsoft.CodeAnalysis.CSharp.CommandLine.UnitTests
{
Expand Down Expand Up @@ -4760,7 +4761,7 @@ public void SdkPathAndLibEnvVariable_Relative_csc()
}

[Fact]
public void UnableWriteOutput()
public void UnableWriteOutput_OutputFileIsDirectory()
{
var tempFolder = Temp.CreateDirectory();
var baseDirectory = tempFolder.ToString();
Expand All @@ -4777,6 +4778,33 @@ public void UnableWriteOutput()
CleanupAllGeneratedFiles(src.Path);
}

[ConditionalFact(typeof(WindowsOnly))]
public void UnableWriteOutput_OutputFileLocked()
{
var tempFolder = Temp.CreateDirectory();
var baseDirectory = tempFolder.ToString();
var filePath = tempFolder.CreateFile("temp").Path;

using var _ = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.None);
var currentProcess = Process.GetCurrentProcess();

var src = Temp.CreateFile("a.cs");
src.WriteAllText("public class C{}");

var outWriter = new StringWriter(CultureInfo.InvariantCulture);
int exitCode = CreateCSharpCompiler(responseFile: null, baseDirectory, ["/nologo", "/preferreduilang:en", "/t:library", "/out:" + filePath, src.ToString()]).Run(outWriter);
Assert.Equal(1, exitCode);
var output = outWriter.ToString().Trim();

var match = Regex.Match(output, @"error CS2012: Cannot open '(?<path>.*)' for writing -- (?<message>.*); file may be locked by '(?<app>.*)' \((?<pid>.*)\)");
Assert.True(match.Success);
Assert.Equal(filePath, match.Groups["path"].Value);
Assert.Contains("testhost", match.Groups["app"].Value);
Assert.Equal(currentProcess.Id, int.Parse(match.Groups["pid"].Value));

CleanupAllGeneratedFiles(src.Path);
}

[Fact]
public void ParseHighEntropyVA()
{
Expand Down
3 changes: 3 additions & 0 deletions src/Compilers/Core/Portable/CodeAnalysisResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -794,4 +794,7 @@
<data name="Type0DoesNotHaveExpectedConstructor" xml:space="preserve">
<value>'{0}' type does not have the expected constructor</value>
</data>
<data name="ExceptionMessage_FileMayBeLockedBy" xml:space="preserve">
<value>{0}; file may be locked by {1}</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis
Expand Down Expand Up @@ -114,7 +115,15 @@ private Stream OpenFileStream()
private void ReportOpenFileDiagnostic(DiagnosticBag diagnostics, Exception e)
{
var messageProvider = _compiler.MessageProvider;
diagnostics.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_CantOpenFileWrite, Location.None, _filePath, e.Message));
var lockedBy = FileLockCheck.TryGetLockingProcessInfos(_filePath);

var message = lockedBy.IsEmpty
? e.Message
: string.Format(CodeAnalysisResources.ExceptionMessage_FileMayBeLockedBy,
e.Message,
string.Join(", ", lockedBy.Select(info => $"'{info.applicationName}' ({info.processId})")));

diagnostics.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_CantOpenFileWrite, Location.None, _filePath, message));
}
}
}
Expand Down
Loading

0 comments on commit c0510e5

Please sign in to comment.