Reputation: 484
I am wondering if there is a way to pass command line arguments to roslyn when compiling and executing code.
My current code for generating a compiler and executing source code looks like this:
CSharpCompilation compilation = CSharpCompilation.Create(Path.GetFileName(assemblyPath))
.WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication))
.AddReferences(references)
.AddSyntaxTrees(syntaxTree);
using (var memStream = new MemoryStream())
{
var result = compilation.Emit(memStream);
if (!result.Success)
{
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
}
}
else
{
memStream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(memStream.ToArray());
var test = assembly;
}
}
The goal is to have some sort of source code like this:
using System;
class Program
{
static string StringToUppercase(string str)
{
return str.ToUppercase();
}
static void Main(string[] args)
{
string str = Console.ReadLine();
string result = StringToUppercase(str);
Console.WriteLine(result);
}
}
Where I can pass a command-line argument in and get the result of Console.WriteLine(). What would be the best way to handle this? The current code does build and will compile and analyze source code.
The code would be written in a .NET core 3.1 mvc web app.
Upvotes: 4
Views: 449
Reputation: 26
if you have more then one Console.ReadLine you can can save the input as text file and read it using StramReader:
var inputFile = folder + "/input.txt";
File.WriteAllLines(inputFile, "your command line input");
using (var consoleout = new StreamWriter(folder + "/output.txt")) {
using (var consolein = new StreamReader(inputFile)) {
Console.SetOut(consoleout);
Console.SetIn(consolein);
assembly.EntryPoint.Invoke(null, new string[] {});
consoleout.Flush();
var resultOutput = File.ReadAllText(folder + "/output.txt");
Console.WriteLine(resultOutput);
}
}
Upvotes: 1
Reputation: 400
I guess you want to pass arguments to your compiled application instead of roslyn :)
Execute the compiled code and use Console.SetOut(TextWriter)
to get its output (example: sof link):
Assembly assembly = Assembly.Load(memStream.ToArray());
// Console.SetOut to a writer
var test = assembly.EntryPoint.Invoke(null, new object[] { "arg1", "arg2" });
// And restore it
or start a new process for it:
memStream.CopyTo(File.OpenWrite("temp.exe"))
// Copied from MSDN
// https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput
using (Process process = new Process())
{
process.StartInfo.FileName = "temp.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
// Synchronously read the standard output of the spawned process.
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();
// Write the redirected output to this application's window.
Console.WriteLine(output);
process.WaitForExit();
}
Upvotes: 1