基于.NET Framework4.7.2的WinForm脚本应用升级C#7:选哪个csc.exe?
我负责维护一个他人开发的可运行C#脚本的Windows Forms应用,该应用基于.NET Framework 4.7.2,以AnyCPU模式编译。它已安装最新稳定版Microsoft.CodeDom.Providers.DotNetCompilerPlatform NuGet包3.6.0,同时使用某一未知旧版本的Roslyn编译器。目前应用可正常编译运行脚本,但仅支持旧版C#语法,我希望将编译器升级至C#7。
我发现DotNetCompilerPlatform包自带多套C#编译器:tools\Roslyn46目录下的编译器文件版本为2.10.0.0(比当前使用的版本稍新),Roslyn472目录下的版本为3.600.20.26904。
我将Roslyn472中的文件复制到输出目录(与旧版本的部署方式一致)并指定路径,但调用CSharpCodeProvider.CompileAssemblyFromFile后,编译结果无错误或警告,却未生成任何程序集。查看生成的命令行后发现,手动执行时该版本csc.exe不兼容部分参数,例如不识别/t:library开关。
编译脚本的代码片段如下:
class CompilerSettings : IProviderOptions { // ... public string CompilerFullPath => "path to csc.exe"; } ... engine = new CSharpCodeProvider( new CompilerSettings() ); parameters = new CompilerParameters { WarningLevel = 3, GenerateInMemory = false, GenerateExecutable = false, OutputAssembly = @"c:\dev\CompiledScript.dll", IncludeDebugInformation = true }; // Add some references: foreach ( string entry in _references ) parameters.ReferencedAssemblies.Add( entry ); ... // files list assembled in advance. result = engine.CompileAssemblyFromFile( parameters, files );
请问应选择哪个版本的编译器?或者是否需要添加特定配置选项?
1. 正确选择编译器版本
应使用Roslyn472目录下的编译器,它是针对.NET Framework 4.7.2优化的版本,完全支持C#7及更高版本的语法特性。之前手动复制文件出现参数不兼容问题,是因为仅复制csc.exe不完整,Roslyn编译器需要配套的依赖dll才能正常工作,手动复制容易缺失文件。
2. 抛弃手动部署,利用NuGet包的自动配置
Microsoft.CodeDom.Providers.DotNetCompilerPlatform NuGet包已经内置了完整的Roslyn编译器部署逻辑,不需要手动复制文件或自定义路径:
- 移除自定义的
CompilerSettings类,直接使用无参数构造函数创建CSharpCodeProvider:engine = new CSharpCodeProvider(); - 这个构造函数会自动读取应用配置文件中的设置,使用NuGet包提供的新版编译器。
3. 配置C#7语法支持
确保app.config中包含以下配置节(NuGet安装时通常会自动添加,若缺失可手动补充):
<configuration> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:7 /nowarn:1659;1699;1701"/> </compilers> </system.codedom> </configuration>
重点是/langversion:7参数,它明确指定编译器使用C#7语法规则。
4. 验证部署完整性
编译项目后,检查输出目录下是否存在roslyn文件夹,里面应包含完整的编译器文件(如csc.exe、VBCSCompiler.exe、Microsoft.CodeAnalysis.dll等)。这是NuGet包自动生成的,确保编译器能正常加载所有依赖。
5. 确认编译参数有效性
你原有的CompilerParameters设置是正确的:
GenerateExecutable = false对应编译器的/t:library参数,新版Roslyn完全支持该参数,之前手动执行报错大概率是因为调用了不完整的编译器文件。
内容的提问来源于stack exchange,提问作者ElDog

