Search code examples
c#compiler-construction.net-4.5csharpcodeprovider

Using CSharpCodeProvider with .net 4.5 beta


I recently installed the Visual Studio 11 Beta, and I'm trying to update an existing 4.0 project to use 4.5. In the program it compiles some dynamically generated code using CSharpCodeProvider.

/// <summary>
/// Compile and return a reference to the compiled assembly
/// </summary>
private Assembly Compile()
{
    var referencedDlls = new List<string>
    {
        "mscorlib.dll",
        "System.dll",
        "System.Core.dll",
    };
    referencedDlls.AddRange(RequiredReferences);

    var parameters = new CompilerParameters(
        assemblyNames: referencedDlls.ToArray(),
        outputName: GeneratedDllFileName,
        // only include debug information if we are currently debugging
        includeDebugInformation: Debugger.IsAttached);
    parameters.TreatWarningsAsErrors = false;
    parameters.WarningLevel = 0;
    parameters.GenerateExecutable = false;
    parameters.GenerateInMemory = false;
    parameters.CompilerOptions = "/optimize+ /platform:x64";

    string[] files = Directory.GetFiles(GenerationDirectory, "*.cs");

    var compiler = new CSharpCodeProvider(
        new Dictionary<string, string> { { "CompilerVersion", "v4.5" } });
    var results = compiler.CompileAssemblyFromFile(parameters, files);

    if (results.Errors.HasErrors)
    {
        string firstError =
            string.Format("Compile error: {0}", results.Errors[0].ToString());
        throw new ApplicationException(firstError);
    }
    else
    {
        return results.CompiledAssembly;
    }
}

The problem comes when I changed the CompilerVersion from { "CompilerVersion", "v4.0" } to { "CompilerVersion", "v4.5" }

I now get an exception

Compiler executable file csc.exe cannot be found.

Is specifying CompilerVersion the wrong way to tell it to use 4.5? Will compiling it as v4.5 even make a difference since the code won't be using any new 4.5 specific features?


Solution

  • It would have helped if you'd given us a short but complete program to demonstrate the problem, but I can verify that with "v4.0" it will work and compile async methods, assuming you're running on a machine with the VS11 beta installed.

    Demonstration:

    using System;
    using System.Collections;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Diagnostics;
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    
    namespace Foo {}
    
    class Program
    {
        static void Main(string[] args)
        {
            var referencedDll = new List<string>
            {
                "mscorlib.dll",
                "System.dll",
                "System.Core.dll",
            };
    
            var parameters = new CompilerParameters(
                 assemblyNames: referencedDll.ToArray(),
                 outputName: "foo.dll",
                 includeDebugInformation: false)
            {
                TreatWarningsAsErrors = true,
                // We don't want to be warned that we have no await!
                WarningLevel = 0,
                GenerateExecutable = false,
                GenerateInMemory = true
            };
    
            var source = new[] { "class Test { static async void Foo() {}}" };
    
            var options = new Dictionary<string, string> {
                 { "CompilerVersion", "v4.0" }
            };
            var compiler = new CSharpCodeProvider(options);
            var results = compiler.CompileAssemblyFromSource(parameters, source);
    
            Console.WriteLine("Success? {0}", !results.Errors.HasErrors);
        }
    }