You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Roslyn程序化创建可直接运行的Windows控制台应用?

解决方案:生成可直接运行的Windows可执行文件

你当前生成的是框架依赖的.NET Core程序集,本质是IL代码,并非原生Windows PE可执行文件,必须依赖dotnet.exe作为CoreCLR宿主才能运行。要生成可直接双击运行的exe,有两种可行方案:


方案一:编译为.NET Framework控制台程序(推荐,实现简单)

如果目标机器已安装.NET Framework(Windows默认预装),可以直接编译为.NET Framework的原生可执行文件,这类exe自带CLR引导逻辑,无需额外宿主。

修改后的代码实现

string codeToCompile = @"
using System;
public class Program
{
    public static void Main()
    {
        Console.WriteLine(""Hello World!"");
        Console.ReadLine();
    }
}";

// 解析代码为语法树
var syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);

// 指定.NET Framework程序集路径(以64位4.8版本为例)
var netFrameworkDir = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.Windows),
    @"Microsoft.NET\Framework64\v4.0.30319"
);

// 引用.NET Framework核心程序集
var refPaths = new[] {
    Path.Combine(netFrameworkDir, "mscorlib.dll"),
    Path.Combine(netFrameworkDir, "System.dll"),
    Path.Combine(netFrameworkDir, "System.Core.dll")
};
var references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();

// 编译为.NET Framework控制台程序
var compilation = CSharpCompilation.Create("output")
                                   .WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication)
                                       .WithTargetFramework(TargetFrameworkMoniker.Net48))
                                   .AddReferences(references)
                                   .AddSyntaxTrees(syntaxTree);

// 输出exe和pdb文件
var emitResult = compilation.Emit("output.exe", "output.pdb");

// 检查编译错误
if (!emitResult.Success)
{
    foreach (var error in emitResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
    {
        Console.WriteLine($"编译错误:{error.GetMessage()}");
    }
}

说明

  • 生成的output.exe可直接在安装了.NET Framework 4.8的Windows机器上运行
  • 若需适配其他.NET Framework版本,修改TargetFrameworkMoniker和对应的程序集路径即可

方案二:生成.NET Core/.NET 5+自包含可执行文件

如果需要跨平台支持,或目标机器未安装.NET Framework,可以生成**自包含部署(SCD)**的可执行文件——这类文件包含了CoreCLR运行时和所有依赖库,无需系统预装.NET环境。

Roslyn仅负责编译IL代码,自包含部署需要借助.NET SDK的发布功能,步骤如下:

步骤1:用Roslyn编译生成程序集DLL

string codeToCompile = @"
using System;
public class Program
{
    public static void Main()
    {
        Console.WriteLine(""Hello World!"");
        Console.ReadLine();
    }
}";

var syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);

var dotNetCoreDir = Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location);
var refPaths = new[] {
    typeof(Object).GetTypeInfo().Assembly.Location,
    typeof(Console).GetTypeInfo().Assembly.Location,
    Path.Combine(dotNetCoreDir, "System.Runtime.dll")
};
var references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();

// 编译为DLL(而非exe,.NET Core的exe只是宿主存根)
var compilation = CSharpCompilation.Create("output")
                                   .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                                   .AddReferences(references)
                                   .AddSyntaxTrees(syntaxTree);

var emitResult = compilation.Emit("output.dll", "output.pdb");

if (!emitResult.Success)
{
    foreach (var error in emitResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
    {
        Console.WriteLine($"编译错误:{error.GetMessage()}");
    }
    return;
}

步骤2:创建临时项目文件并执行发布

// 定义自包含部署的项目配置(以.NET 6为例)
var csprojContent = @"<Project Sdk=""Microsoft.NET.Sdk"">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <SelfContained>true</SelfContained>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include=""output.dll"">
      <HintPath>output.dll</HintPath>
    </Reference>
  </ItemGroup>
</Project>";

// 写入临时项目文件
File.WriteAllText("temp.csproj", csprojContent);

// 调用dotnet publish生成自包含可执行文件
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "dotnet";
process.StartInfo.Arguments = "publish temp.csproj -o publish";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();

string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();

if (process.ExitCode != 0)
{
    Console.WriteLine($"发布失败:{error}");
}
else
{
    Console.WriteLine($"自包含可执行文件已生成:publish\\output.exe");
}

// 清理临时文件
File.Delete("temp.csproj");

说明

  • RuntimeIdentifier可根据目标平台修改(如win-x86、linux-x64)
  • PublishSingleFile可选,开启后会生成单个合并的exe文件
  • PublishTrimmed可选,开启后会裁剪未使用的依赖,减小文件体积

内容的提问来源于stack exchange,提问作者Rafi Henig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:30:56