diff --git a/documentation/general/dotnet-run-file.md b/documentation/general/dotnet-run-file.md
index f3b723d872f1..a4baf3c4e21b 100644
--- a/documentation/general/dotnet-run-file.md
+++ b/documentation/general/dotnet-run-file.md
@@ -65,7 +65,11 @@ For example, the remaining command-line arguments after the first argument (the
(except for the arguments recognized by `dotnet run` unless they are after the `--` separator)
and working directory is not changed (e.g., `cd /x/ && dotnet run /y/file.cs` runs the program in directory `/x/`).
-`dotnet path.cs` is a shortcut for `dotnet run path.cs` provided that `path.cs` is a valid [target path](#target-path).
+If a dash (`-`) is given instead of the target path (i.e., `dotnet run -`), the C# file to be executed is read from the standard input.
+In this case, the current working directory is not used to search for other files (launch profiles, other sources in case of multi-file apps);
+the compilation consists solely of the single file read from the standard input.
+
+`dotnet path.cs` is a shortcut for `dotnet run path.cs` provided that `path.cs` is a valid [target path](#target-path) (`dotnet -` is currently not supported).
### Other commands
@@ -247,10 +251,6 @@ This section outlines potential future enhancements and alternatives considered.
We could allow folders as the target path in the future (e.g., `dotnet run ./my-app/`).
-An option like `dotnet run --cs-from-stdin` could read the C# file from standard input.
-In this case, the current working directory would not be used to search for project or other C# files;
-the compilation would consist solely of the single file read from standard input.
-
Similarly, it could be possible to specify the whole C# source text in a command-line argument
like `dotnet run --cs-code 'Console.WriteLine("Hi")'`.
diff --git a/src/Cli/dotnet/Commands/CliCommandStrings.resx b/src/Cli/dotnet/Commands/CliCommandStrings.resx
index 0d75f1886f0d..b49657f83019 100644
--- a/src/Cli/dotnet/Commands/CliCommandStrings.resx
+++ b/src/Cli/dotnet/Commands/CliCommandStrings.resx
@@ -1535,6 +1535,10 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+
Warning: Binary log option was specified but build will be skipped because output is up to date, specify '--no-cache' to force build.{Locked="--no-cache"}
diff --git a/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs b/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
index dcf6d0bf3363..bea850fe2a45 100644
--- a/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
+++ b/src/Cli/dotnet/Commands/Run/Api/RunApiCommand.cs
@@ -95,7 +95,8 @@ public override RunApiOutput Execute()
var runCommand = new RunCommand(
noBuild: false,
- projectFileOrDirectory: null,
+ projectFileFullPath: null,
+ entryPointFileFullPath: EntryPointFileFullPath,
launchProfile: null,
noLaunchProfile: false,
noLaunchProfileArguments: false,
@@ -104,7 +105,8 @@ public override RunApiOutput Execute()
interactive: false,
verbosity: VerbosityOptions.quiet,
restoreArgs: [],
- args: [EntryPointFileFullPath],
+ args: [],
+ readCodeFromStdin: false,
environmentVariables: ReadOnlyDictionary.Empty);
runCommand.TryGetLaunchProfileSettingsIfNeeded(out var launchSettings);
diff --git a/src/Cli/dotnet/Commands/Run/RunCommand.cs b/src/Cli/dotnet/Commands/Run/RunCommand.cs
index e23b6fb48517..a98c3b52148f 100644
--- a/src/Cli/dotnet/Commands/Run/RunCommand.cs
+++ b/src/Cli/dotnet/Commands/Run/RunCommand.cs
@@ -3,6 +3,7 @@
using System.Collections.Immutable;
using System.CommandLine;
+using System.CommandLine.Parsing;
using System.Diagnostics;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
@@ -22,11 +23,6 @@ public class RunCommand
{
public bool NoBuild { get; }
- ///
- /// Value of the --project option.
- ///
- public string? ProjectFileOrDirectory { get; }
-
///
/// Full path to a project file to run.
/// if running without a project file
@@ -39,6 +35,13 @@ public class RunCommand
///
public string? EntryPointFileFullPath { get; }
+ ///
+ /// Whether dotnet run - is being executed.
+ /// In that case, points to a temporary file
+ /// containing all text read from the standard input.
+ ///
+ public bool ReadCodeFromStdin { get; }
+
public string[] Args { get; set; }
public bool NoRestore { get; }
public bool NoCache { get; }
@@ -63,7 +66,8 @@ public class RunCommand
public RunCommand(
bool noBuild,
- string? projectFileOrDirectory,
+ string? projectFileFullPath,
+ string? entryPointFileFullPath,
string? launchProfile,
bool noLaunchProfile,
bool noLaunchProfileArguments,
@@ -73,12 +77,16 @@ public RunCommand(
VerbosityOptions? verbosity,
string[] restoreArgs,
string[] args,
+ bool readCodeFromStdin,
IReadOnlyDictionary environmentVariables)
{
+ Debug.Assert(projectFileFullPath is null ^ entryPointFileFullPath is null);
+ Debug.Assert(!readCodeFromStdin || entryPointFileFullPath is not null);
+
NoBuild = noBuild;
- ProjectFileOrDirectory = projectFileOrDirectory;
- ProjectFileFullPath = DiscoverProjectFilePath(projectFileOrDirectory, ref args, out string? entryPointFileFullPath);
+ ProjectFileFullPath = projectFileFullPath;
EntryPointFileFullPath = entryPointFileFullPath;
+ ReadCodeFromStdin = readCodeFromStdin;
LaunchProfile = launchProfile;
NoLaunchProfile = noLaunchProfile;
NoLaunchProfileArguments = noLaunchProfileArguments;
@@ -117,6 +125,7 @@ public int Execute()
if (EntryPointFileFullPath is not null)
{
+ Debug.Assert(!ReadCodeFromStdin);
projectFactory = CreateVirtualCommand().PrepareProjectInstance().CreateProjectInstance;
}
}
@@ -180,7 +189,7 @@ internal bool TryGetLaunchProfileSettingsIfNeeded(out ProjectLaunchSettingsModel
return true;
}
- var launchSettingsPath = TryFindLaunchSettings(ProjectFileFullPath ?? EntryPointFileFullPath!);
+ var launchSettingsPath = ReadCodeFromStdin ? null : TryFindLaunchSettings(ProjectFileFullPath ?? EntryPointFileFullPath!);
if (!File.Exists(launchSettingsPath))
{
if (!string.IsNullOrEmpty(LaunchProfile))
@@ -437,7 +446,7 @@ private static void ThrowUnableToRunError(ProjectInstance project)
project.GetPropertyValue("OutputType")));
}
- private static string? DiscoverProjectFilePath(string? projectFileOrDirectoryPath, ref string[] args, out string? entryPointFilePath)
+ private static string? DiscoverProjectFilePath(string? projectFileOrDirectoryPath, bool readCodeFromStdin, ref string[] args, out string? entryPointFilePath)
{
bool emptyProjectOption = false;
if (string.IsNullOrWhiteSpace(projectFileOrDirectoryPath))
@@ -453,7 +462,7 @@ private static void ThrowUnableToRunError(ProjectInstance project)
// If no project exists in the directory and no --project was given,
// try to resolve an entry-point file instead.
entryPointFilePath = projectFilePath is null && emptyProjectOption
- ? TryFindEntryPointFilePath(ref args)
+ ? TryFindEntryPointFilePath(readCodeFromStdin, ref args)
: null;
if (entryPointFilePath is null && projectFilePath is null)
@@ -480,16 +489,27 @@ private static void ThrowUnableToRunError(ProjectInstance project)
return projectFiles[0];
}
- static string? TryFindEntryPointFilePath(ref string[] args)
+ static string? TryFindEntryPointFilePath(bool readCodeFromStdin, ref string[] args)
{
- if (args is not [{ } arg, ..] ||
- !VirtualProjectBuildingCommand.IsValidEntryPointPath(arg))
+ if (args is not [{ } arg, ..])
{
return null;
}
+ if (!readCodeFromStdin)
+ {
+ if (VirtualProjectBuildingCommand.IsValidEntryPointPath(arg))
+ {
+ arg = Path.GetFullPath(arg);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
args = args[1..];
- return Path.GetFullPath(arg);
+ return arg;
}
}
@@ -521,9 +541,44 @@ public static RunCommand FromParseResult(ParseResult parseResult)
restoreArgs.AddRange(binLogArgs);
}
+ // Only consider `-` to mean "read code from stdin" if it is before double dash `--`
+ // (otherwise it should be fowarded to the target application as its command-line argument).
+ bool readCodeFromStdin = nonBinLogArgs is ["-", ..] &&
+ parseResult.Tokens.TakeWhile(static t => t.Type != TokenType.DoubleDash)
+ .Any(static t => t is { Type: TokenType.Argument, Value: "-" });
+
+ string? projectOption = parseResult.GetValue(RunCommandParser.ProjectOption);
+
+ string[] args = [.. nonBinLogArgs];
+ string? projectFilePath = DiscoverProjectFilePath(projectOption, readCodeFromStdin, ref args, out string? entryPointFilePath);
+
+ bool noBuild = parseResult.HasOption(RunCommandParser.NoBuildOption);
+
+ if (readCodeFromStdin && entryPointFilePath != null)
+ {
+ Debug.Assert(projectFilePath is null && entryPointFilePath is "-");
+
+ if (noBuild)
+ {
+ throw new GracefulException(CliCommandStrings.InvalidOptionForStdin, RunCommandParser.NoBuildOption.Name);
+ }
+
+ // If '-' is specified as the input file, read all text from stdin into a temporary file and use that as the entry point.
+ entryPointFilePath = Path.GetTempFileName();
+ using (var stdinStream = Console.OpenStandardInput())
+ using (var fileStream = File.OpenWrite(entryPointFilePath))
+ {
+ stdinStream.CopyTo(fileStream);
+ }
+
+ Debug.Assert(nonBinLogArgs[0] == "-");
+ nonBinLogArgs[0] = entryPointFilePath;
+ }
+
var command = new RunCommand(
- noBuild: parseResult.HasOption(RunCommandParser.NoBuildOption),
- projectFileOrDirectory: parseResult.GetValue(RunCommandParser.ProjectOption),
+ noBuild: noBuild,
+ projectFileFullPath: projectFilePath,
+ entryPointFileFullPath: entryPointFilePath,
launchProfile: parseResult.GetValue(RunCommandParser.LaunchProfileOption) ?? string.Empty,
noLaunchProfile: parseResult.HasOption(RunCommandParser.NoLaunchProfileOption),
noLaunchProfileArguments: parseResult.HasOption(RunCommandParser.NoLaunchProfileArgumentsOption),
@@ -532,7 +587,8 @@ public static RunCommand FromParseResult(ParseResult parseResult)
interactive: parseResult.GetValue(RunCommandParser.InteractiveOption),
verbosity: parseResult.HasOption(CommonOptions.VerbosityOption) ? parseResult.GetValue(CommonOptions.VerbosityOption) : null,
restoreArgs: [.. restoreArgs],
- args: [.. nonBinLogArgs],
+ args: args,
+ readCodeFromStdin: readCodeFromStdin,
environmentVariables: parseResult.GetValue(CommonOptions.EnvOption) ?? ImmutableDictionary.Empty
);
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
index ba28b98acfff..b468dc23331d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
index 6d12b3b73c6d..d719ba37e98e 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
index 7cea1d5bbe96..d961ac571997 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
index 735acf92f982..1c75a5a114c7 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
index 532c09dc5165..256db7517884 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
index 2d73b067eef5..ffe3037fc535 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
index efd09bb2926b..0d29f919d80d 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
index 580751117300..8fea0d19b119 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
index 92d9adb2d5fb..078d04c02bb0 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
index 788593aa84f3..9feb1fa5c88b 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
index a1a3e504e551..612d541373a7 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
index 7287768e5e23..3606de77cb4a 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
index 5ef7765135d7..4e75a93f0900 100644
--- a/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
@@ -1451,6 +1451,11 @@ Make the profile names distinct.
Cannot combine option '{0}' and '{1}'.{0} and {1} are option names like '--no-build'.
+
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ Cannot specify option '{0}' when also using '-' to read the file from standard input.
+ {0} is an option name like '--no-build'.
+ The '#:project' directive at '{0}' is invalid: {1}The '#:project' directive at '{0}' is invalid: {1}
diff --git a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
index 02a5bccdd43c..b31da0a26864 100644
--- a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
+++ b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
@@ -220,6 +220,50 @@ public void FilePath_AsProjectArgument()
.And.HaveStdErrContaining(CliCommandStrings.RunCommandException);
}
+ ///
+ /// dotnet run - reads the C# code from stdin.
+ ///
+ [Fact]
+ public void ReadFromStdin()
+ {
+ new DotnetCommand(Log, "run", "-")
+ .WithStandardInput("""
+ Console.WriteLine("Hello from stdin");
+ Console.WriteLine("Read: " + (Console.ReadLine() ?? "null"));
+ """)
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOut("""
+ Hello from stdin
+ Read: null
+ """);
+ }
+
+ [Fact]
+ public void ReadFromStdin_NoBuild()
+ {
+ new DotnetCommand(Log, "run", "-", "--no-build")
+ .Execute()
+ .Should().Fail()
+ .And.HaveStdErrContaining(string.Format(CliCommandStrings.InvalidOptionForStdin, RunCommandParser.NoBuildOption.Name));
+ }
+
+ ///
+ /// dotnet run -- - should NOT read the C# file from stdin,
+ /// the hyphen should be considred an app argument instead since it's after --.
+ ///
+ [Fact]
+ public void ReadFromStdin_AfterDoubleDash()
+ {
+ var testInstance = _testAssetsManager.CreateTestDirectory();
+ new DotnetCommand(Log, "run", "--", "-")
+ .WithWorkingDirectory(testInstance.Path)
+ .WithStandardInput("""Console.WriteLine("stdin code");""")
+ .Execute()
+ .Should().Fail()
+ .And.HaveStdErrContaining(string.Format(CliCommandStrings.RunCommandExceptionNoProjects, testInstance.Path, RunCommandParser.ProjectOption.Name));
+ }
+
///
/// dotnet run folder without a project file is not supported.
///