如何将单个代码作为字符串编译为工作且独立的 .exe 文件?我尝试了三种不同的方法:
CSharpCodeProvider
:这工作正常,但我需要它用于较新的.NET 7,并且此解决方案不适用于此版本。CSharpScript
:这也可以正常工作,但我需要将实际生成的程序集存储到磁盘上的工作 .exe 文件中。CSharpCompiler
:我想我需要这个,但是,我无法让它工作,我仍然在引用方面遇到一些问题。有没有办法自动添加这些引用?总是,当我添加引用时,它会报告缺少另一个引用。
我正在使用的代码,但不起作用。
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
var code = """
using System;
// Just a demo program.
Console.WriteLine("Hello, World!");
""";
var compilation = CSharpCompilation.Create("DynamicCode")
.WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication))
.AddReferences(
MetadataReference.CreateFromFile(Assembly.Load("System.Private.CoreLib").Location),
MetadataReference.CreateFromFile(Assembly.Load("System").Location)
)
.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(code));
// Note: I also tried adding references using the typeof keyword,
// so like typeof(object).Assembly.Location, but that also didn't work.
using var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);
if (emitResult.Success)
{
var exePath = "DynamicCode.exe";
File.WriteAllBytes(exePath, stream.ToArray());
Console.WriteLine($"DynamicCode.exe saved successfully.");
}
else
{
Console.WriteLine("Failed:");
foreach (var diagnostic in emitResult.Diagnostics)
{
Console.WriteLine(diagnostic);
}
}
我从输出中得到了什么(编译时):
(4,1): error CS0103: Console name does not exist in the current context.
当我使用以下引用而不是在代码中使用时:
var compilation = CSharpCompilation.Create("DynamicCode")
.WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication))
.AddReferences(AppDomain.CurrentDomain.GetAssemblies().Select(x => MetadataReference.CreateFromFile(x.Location)))
.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(code));
我在运行应用程序时收到此消息,加上输出程序集约为 3kB,这对我来说似乎很奇怪:
Unhandled Exception: System.IO.FileNotFoundException: Unable to load file or assembly System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, or one of its dependencies. The system cannot find the specified file.
那么我做错了什么吗?有没有一种自动添加引用的方法,或者一些“更好”的添加引用的方法?我尝试了诸如ChatGPT之类的东西,但它没有帮助我,所以我不知道问题出在哪里。
如果实际的解决方案有效,是否有办法将程序集编译成.NET Framework v4.7.2?我想保持与旧平台的兼容性,但我的项目是用.NET 7编码的,所以
CSharpCodeProvider
无法使用。
回答1个问题: 要使用控制台调用,您可能需要库的链接
System.Console
问题 2 的回答:我使用类似的方法来获取库的路径:
var path = Path.GetDirectoryName(typeof(object).Assembly.Location)!;
var consoleAssemblyPath = Path.Combine(DefaultAssemblysPath, "System.Console.dll");
var rumtimeAssemblyPath = Path.Combine(DefaultAssemblysPath, "System.Runtime.dll");