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

使用Roslyn与.NET Core时,如何解决System.Windows.Forms命名空间不存在问题

使用Roslyn运行时编译WinForms代码的问题

我正在开发一个基于Roslyn的C#代码运行时编译系统,通过以下代码添加程序集引用(传入程序集完整文件名):

public bool AddAssembly(string assemblyDll)
{
     if (string.IsNullOrEmpty(assemblyDll)) return false;

     var file = Path.GetFullPath(assemblyDll);

     if (!File.Exists(file))
     {
         // 检查框架或专用运行时应用文件夹
         var path = Path.GetDirectoryName(typeof(object).Assembly.Location);
         file = Path.Combine(path, assemblyDll);

         if (!File.Exists(file))
             return false;
     }

     if (References.Any(r => r.FilePath == file)) 
         return true;

     try
     {
         var reference = MetadataReference.CreateFromFile(file);
         References.Add(reference);
     }
     catch
     {
         return false;
     }

     return true;
}

此前功能正常,但尝试编译WinForms窗体代码时,即便已添加System.Windows.Forms.dll程序集引用,仍报错:

Type or namespace name "Forms" does not exist in the namespace 'System.Windows'

查资料得知,在Visual Studio中需编辑.csproj文件添加以下配置解决:

<UseWindowsForms>true</UseWindowsForms>

请问如何让Roslyn识别我要使用WinForms窗体的需求?


解决方案

Roslyn编译WinForms代码时,仅添加程序集引用不够,还需要在编译配置中明确启用WinForms相关支持,对应Visual Studio里<UseWindowsForms>true</UseWindowsForms>的作用,具体操作如下:

  1. 设置编译输出类型为Windows应用
    创建CSharpCompilation时,将OutputKind指定为WindowsApplication,这会告诉编译器生成WinForms兼容的可执行文件:

    var compilationOptions = new CSharpCompilationOptions(OutputKind.WindowsApplication);
    
  2. 添加WinForms专属编译符号
    通过定义WINDOWS_FORMS编译符号,让编译器启用WinForms相关的语法和类型支持:

    compilationOptions = compilationOptions.WithDefineSymbols("WINDOWS_FORMS");
    
  3. 补全依赖程序集引用
    除了System.Windows.Forms.dll,还需添加System.Drawing.dll(WinForms的核心依赖),确保引用的是对应.NET版本的正确路径(.NET Framework从GAC/框架目录获取,.NET 6+从运行时目录获取)。

  4. 完整编译示例
    整合上述配置的完整代码片段:

    // 解析WinForms代码为语法树
    var syntaxTree = CSharpSyntaxTree.ParseText(@"
        using System.Windows.Forms;
    
        public class MyWinForm : Form
        {
            public MyWinForm()
            {
                Text = ""Roslyn WinForms Demo"";
                Size = new System.Drawing.Size(300, 200);
            }
        }
    ");
    
    // 配置编译选项
    var compilationOptions = new CSharpCompilationOptions(OutputKind.WindowsApplication)
        .WithPlatform(Platform.AnyCpu)
        .WithDefineSymbols("WINDOWS_FORMS");
    
    // 收集必要的程序集引用
    var references = new List<MetadataReference>
    {
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(Form).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(System.Drawing.Size).Assembly.Location)
    };
    
    // 创建编译对象并执行编译
    var compilation = CSharpCompilation.Create(
        "WinFormsDynamicAssembly",
        new[] { syntaxTree },
        references,
        compilationOptions
    );
    
    using var ms = new MemoryStream();
    var emitResult = compilation.Emit(ms);
    
    if (!emitResult.Success)
    {
        // 输出编译错误
        foreach (var error in emitResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
        {
            Console.WriteLine($"编译错误:{error.GetMessage()}");
        }
    }
    else
    {
        // 加载编译后的程序集并运行窗体
        ms.Seek(0, SeekOrigin.Begin);
        var assembly = Assembly.Load(ms.ToArray());
        var formType = assembly.GetType("MyWinForm");
        Application.Run((Form)Activator.CreateInstance(formType));
    }
    

核心就是通过OutputKind.WindowsApplication和WINDOWS_FORMS符号,让Roslyn启用WinForms的编译支持,再配合完整的依赖引用,就能解决找不到System.Windows.Forms命名空间的问题。


内容的提问来源于stack exchange,提问作者Andy L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:55:01