Using C# 6 features with CodeDomProvider (Roslyn)

前端 未结 5 1689
梦如初夏
梦如初夏 2020-12-01 08:56
CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider( \"CSharp\" );

CompilerParameters objCompilerParameters = new CompilerParameters();

...

CompilerR         


        
5条回答
  •  自闭症患者
    2020-12-01 09:32

    Update: March 2018

    Word of caution, NuGet version 1.0.6 ... 1.0.8 will not copy the /roslyn folder to the build output directory on non-web projects. Best stick with 1.0.5 https://github.com/aspnet/RoslynCodeDomProvider/issues/38

    Run-time compilation using C#6 features requires a new compiler, as @thomas-levesque mentioned. This compiler can be installed by using the nuget package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.

    For desktop applications, there's a problem. The ASP.NET team, in their infinite wisdom have hard-coded the path to the compiler as \bin\roslyn\csc.exe See discussion at https://github.com/dotnet/roslyn/issues/9483

    If your desktop application is compiled to \myapp\app.exe, the roslyn compiler will be located at \myapp\roslyn\csc.exe, BUT THE CSharpCodeProvider WILL RESOLVE csc.exe as \myapp\bin\roslyn\csc.exe

    As far as I can tell, you have two options

    1. Create a post-build and/or installation routine that will move the \roslyn subdirectory to \bin\roslyn.
    2. Fix the runtime code through reflection black magic.

    Here is #2, by exposing the CSharpCodeProvider as a property in a utility class.

    using System.Reflection;
    using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
    
    static Lazy CodeProvider { get; } = new Lazy(() => {
        var csc = new CSharpCodeProvider();
        var settings = csc
            .GetType()
            .GetField("_compilerSettings", BindingFlags.Instance | BindingFlags.NonPublic)
            .GetValue(csc);
    
        var path = settings
            .GetType()
            .GetField("_compilerFullPath", BindingFlags.Instance | BindingFlags.NonPublic);
    
        path.SetValue(settings, ((string)path.GetValue(settings)).Replace(@"bin\roslyn\", @"roslyn\"));
    
        return csc;
    });
    

提交回复
热议问题