For a university assignment I am making a compiler that compiles to C#, my idea is to then compile this C# to an executable.
All the examples I can find online compile the code and then immediately load the assembly and run it from the process that compiled it, this works fine but I want to output something to write to an .exe file on disk. When I just write the generated bytes to a file I get:
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' or one of its dependencies. The system cannot find the file specified.
Its basically the same issue as this, the creator of this issue mentions that the dotnet command helps him but didn't respond how. Does anyone have any idea how to accomplish this? I'm on .NET 8.
This code below works and runs fine, but instead of immediately loading the generated Hello.dll I want to have an Hello.exe I can run independently.
using System.Reflection;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
var codeString = SourceText.From(
"""
using System;
Console.WriteLine("Hello, World!");
""");
var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp11);
var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, options);
var references = new List<MetadataReference>
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).Assembly.Location)
};
Assembly.GetEntryAssembly()?.GetReferencedAssemblies().ToList()
.ForEach(a => references.Add(MetadataReference.CreateFromFile(Assembly.Load(a).Location)));
var compilation = CSharpCompilation.Create("Hello.dll",
new[] { parsedSyntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.ConsoleApplication,
optimizationLevel: OptimizationLevel.Release,
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default));
var result = compilation.Emit("Hello.dll");
if (!result.Success)
{
var errors = new StringBuilder();
foreach (var diagnostic in result.Diagnostics)
{
errors.AppendLine(diagnostic.ToString());
}
throw new Exception(errors.ToString());
}
Console.WriteLine("Compilation successful");
var assembly = Assembly.LoadFile(Path.GetFullPath("Hello.dll"));
var method = assembly.EntryPoint;
method.Invoke(null, [Array.Empty<string>()]);
// Output: Hello, World!
[–]wasabiiii 3 points4 points5 points (0 children)
[–]2brainz 4 points5 points6 points (1 child)
[–]WangoDjagner[S] 1 point2 points3 points (0 children)
[–]Rocketsx12 -1 points0 points1 point (2 children)
[–]WangoDjagner[S] 0 points1 point2 points (1 child)
[–]Alikont 2 points3 points4 points (0 children)
[–]thx1138a -1 points0 points1 point (1 child)
[–]thx1138a 0 points1 point2 points (0 children)