Как заставить CSharpCodeProvider компилироваться для конкретной целевой платформы?

У меня есть решение, которое содержит проекты С#, некоторые netstandard 2.0 и другие .net4.7. Стартовый проект, конечно же, net47.

В какой-то момент проект создает код с помощью CodeDom и компилирует его с помощью CSharpCodeProvider. Проблема в том, что на некоторых машинах он пытается скомпилировать сборку для .netstandard и терпит неудачу. Ожидается сбой: сгенерированная сборка ссылается на EF, которая доступна только для полной .net framework.

Как я могу заставить CSharpCodeProvider компилироваться против .net47?

public bool GenerateAssembly(
        CodeDomBusinessCode compileUnit
        , string fileName
        , string assembliesPath
        , out IEnumerable<string> errors)
    {
        var provider = new CSharpCodeProvider();
        var parameters = new CompilerParameters
        {
            GenerateExecutable = false,
            OutputAssembly = fileName,
            GenerateInMemory = false
        };
        parameters.ReferencedAssemblies.Add("System.dll");
        parameters.ReferencedAssemblies.Add("System.Runtime.dll");
        parameters.ReferencedAssemblies.Add("System.Core.dll");
        parameters.ReferencedAssemblies.Add("System.ComponentModel.Composition.dll");
        parameters.ReferencedAssemblies.Add(Path.Combine(assembliesPath, "EntityFramework.dll"));
        parameters.ReferencedAssemblies.Add("System.ComponentModel.DataAnnotations.dll");
        parameters.ReferencedAssemblies.Add(Path.Combine(assembliesPath, "GlobalE.Server.Contracts.dll"));

        var results = provider.CompileAssemblyFromDom(parameters, compileUnit.Code);
        if (results.Errors.Count > 0)
        {
            errors = results.Errors.OfType<CompilerError>().Select(x => x.ToString());
            return false;
        }
        errors = null;
        return true;
    }

Ошибка:

error CS0012: The type 'System.IDisposable' is defined in an assembly
 that is not referenced. You must add a reference to assembly 
'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

ОБНОВЛЕНИЕ: Если я изменю все проекты на net47 (чтобы в решении не было проекта netstandard), ошибка исчезнет, ​​но я хочу сохранить как можно больше проектов на netstandard.


person Alireza    schedule 10.11.2017    source источник
comment
@HansPassant Ну EF точно присутствует: я его вижу в каталоге bin, а когда приношу с другого компа скомпилированную сборку (только нашу сборку, а не ее зависимости) все начинает работать. Судя по всему, это только этап компиляции. Обновлен вопрос, чтобы включить фактическое сообщение об ошибке.   -  person Alireza    schedule 10.11.2017
comment
Дубликат stackoverflow. com/questions/13253967/ ?   -  person Simon Mourier    schedule 20.11.2019
comment
CSharpCodeProvider является устаревшим, он может ориентироваться только на установленную версию .NET, допустимые параметры для CompilerVersion: 2.0, 3.0 или 4.0. Ваша программа будет скомпилирована C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe. Это устаревший компилятор C#, последний раз обновленный в .NET 4.5, он ничего не знает о .NETStandard. Вам нужно будет принести свой.   -  person Hans Passant    schedule 24.11.2019


Ответы (2)


на основании вашей ошибки вы должны добавить «netstandard.dll» в качестве ссылок, и это может привести к тому, что в .net 4.7 «System.IDisposable» находится в «mscorlib.dll», а в .netstatndard — в «netstandard.dll». ".

person Pbehin    schedule 24.11.2019

Попробуй это

var options = new Dictionary<string, string> 
              {
                  { "CompilerVersion", "v4.7" }
              };
var provider = new CSharpCodeProvider(options);
person mfkl    schedule 20.11.2019