15

Using the C# code provider and the ICodeCompiler.CompileAssemblyFromSource method, I am attempting to compile a code file in order to produce an executable assembly.

The code that I would like to compile makes use of features such as optional parameters and extension methods that are only available when using the language C# 4.

Having said that, the code that I would like to compile only requires (and needs) to target version 2.0 of the .NET Framework.


Using the proceeding code it is possible to avoid any compile-time errors pertaining to syntax however, the resulting assembly will target version 4.0 of the framework which is undesirable.

var compiler = new CSharpCodeProvider(
        new Dictionary<string, string> { { "CompilerVersion", "v4.0" } } );

How can I make is so that the code provider targets language version 4.0 but produces an assembly that only requires version 2.0 of the framework?

Caster Troy
  • 2,796
  • 2
  • 25
  • 45
  • 1
    You're already targeting a specific *compiler* version - what you don't know is how to target a specific *framework* version. I suggest you update your question (particularly the title) accordingly. – Jon Skeet Nov 16 '13 at 13:29
  • Have you tried specifying the [`CompilerParameters`](http://msdn.microsoft.com/en-us/library/a35e5939.aspx) when you later compile, and specifically passing a set of assemblies which match the framework you are trying to target? – Ben Voigt Nov 19 '13 at 06:36
  • You may also need to use the `CompilerOptions` property to pass `/nostdlib+ /noconfig` (in additional to passing the right version of the system assemblies). See http://blogs.msdn.com/b/ed_maurer/archive/2010/03/31/multi-targeting-and-the-c-and-vb-compilers.aspx – Ben Voigt Nov 19 '13 at 06:43
  • Wow... there's [this question](http://stackoverflow.com/questions/7222356/how-do-i-select-the-target-framework-of-a-codedom-compiler-using-c) that asks the right thing but all the answers are wrong (specify language version and compiler, not framework) – Ben Voigt Nov 19 '13 at 06:44

1 Answers1

12

You need to instruct the C# compiler (that CSharpCodeProvider uses indirectly) that you want to link to another mscorlib.dll, using the /nostdlib option. Here is a sample that should do it:

static void Main(string[] args)
{
    // defines references
    List<string> references = new List<string>();

    // get a reference to the mscorlib you want
    var mscorlib_2_x86 = Path.Combine(
                         Environment.GetFolderPath(Environment.SpecialFolder.Windows),
                         @"Microsoft.NET\Framework\v2.0.50727\mscorlib.dll");
    references.Add(mscorlib_2_x86);

    // ... add other references (System.dll, etc.)

    var provider = new CSharpCodeProvider(
                   new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
    var parameters = new CompilerParameters(references.ToArray(), "program.exe");
    parameters.GenerateExecutable = true;

    // instruct the compiler not to use the default mscorlib
    parameters.CompilerOptions = "/nostdlib";              

    var results = provider.CompileAssemblyFromSource(parameters,
        @"using System;

        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(""Hello world from CLR version: "" + Environment.Version);
            }
        }");
}

If you run this, it should compile a program.exe file. If you run that file, it should display something like this:

Hello world from CLR version: 2.0.50727.7905
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298