2015-07-26 24 views
21
CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider("CSharp"); 

CompilerParameters objCompilerParameters = new CompilerParameters(); 

... 

CompilerResults objCompileResults = objCodeCompiler.CompileAssemblyFromFile(objCompilerParameters, files.ToArray()); 

Kiedy skompilować moje pliki uzyskać:C# 6 funkcje z CodeDomProvider (rosyln)

FileFunctions.cs(347): Error: Unexpected character '$'

Czy ktoś wie jak dostać interpolacji ciąg roboczy z CodeDom kompilacji?

znalazłem ten link: How to target .net 4.5 with CSharpCodeProvider?

więc próbowałem:

 var providerOptions = new Dictionary<string, string>(); 
    providerOptions.Add("CompilerVersion", "v4.0"); 

    // Instantiate the compiler. 
    CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider("CSharp", providerOptions); 

Ale nadal ten sam błąd.

Zaktualizowałem także docelowy system do .NET Framework 4.6.

UWAGA: Nie mogę określić "v4.5" lub "v4.6" czy dostanę:

************** Exception Text ************** 
System.InvalidOperationException: Compiler executable file csc.exe cannot be found. 
    at System.CodeDom.Compiler.RedistVersionInfo.GetCompilerPath(IDictionary`2 provOptions, String compilerExecutable) 
    at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames) 
    at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, String[] fileNames) 
    at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromFile(CompilerParameters options, String[] fileNames) 
    at Dynamic.CodeDOMCompiler.CompileAllCodeFiles() in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\Core\CodeDOMCompiler.cs:line 93 
    at NewForm.InitializeSystem() in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\NewForm.cs:line 179 
    at NewForm.NewForm_Load(Object sender, EventArgs e) in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\NewForm.cs:line 111 
    at System.Windows.Forms.Form.OnLoad(EventArgs e) 

Próbowałem przy użyciu sugestię Thomas Levesque:

CodeDomProvider objCodeCompiler = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); 

Ale wtedy pojawia się:

************** Exception Text ************** 
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\bin\x86\Debug\bin\roslyn\csc.exe'. 
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) 
    at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.get_CompilerName() 
    at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.FromFileBatch(CompilerParameters options, String[] fileNames) 
    at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.CompileAssemblyFromFileBatch(CompilerParameters options, String[] fileNames) 
    at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromFile(CompilerParameters options, String[] fileNames) 
    at Dynamic.CodeDOMCompiler.CompileAllCodeFiles() in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\Core\CodeDOMCompiler.cs:line 87 
    at NewForm.InitializeSystem() in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\NewForm.cs:line 179 
    at NewForm.NewForm_Load(Object sender, EventArgs e) in C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\NewForm.cs:line 111 
    at System.Windows.Forms.Form.OnLoad(EventArgs e) 

nie jestem pewien, dlaczego stara się szukać „csc.exe” w podfolderze moim katalogu bin.

Ta ścieżka istnieje:

C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\bin\x86\Debug\roslyn

Ale szukałem:

C:\Users\Derek.Morin\Documents\Visual Studio 2010\Projects\ScriptCode\ScriptCode.ConvertedToC#\bin\x86\Debug\bin\roslyn\csc.exe

+0

Jaką wersją .NET Framework jest twój projekt? –

+0

Zaktualizowałem moje pytanie o szczegóły ".NET Framework 4.6". Powinienem zauważyć, że ten sam kod kompiluje się dobrze w Visual Studio, ale kiedy próbuję skompilować go za pomocą CodeDom, pojawia się problem. – Derek

+3

Ta funkcja zależy od wersji języka C#, a nie od wersji .NET Framework. – hvd

Odpowiedz

16

Wbudowany dostawcy CodeDOM nie obsługuje C# 6. Zastosowanie ten zamiast:

https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/

Jest oparty na Roslyn i obsługuje funkcje C# 6.

Wystarczy zmienić tę linię:

CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider("CSharp"); 

do tego:

CodeDomProvider objCodeCompiler = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); 
+2

"Wbudowany dostawca CodeDOM nie obsługuje C# 6": czy możesz podać źródła tych informacji do dalszego rozważenia? Wydaje się dziwne, że 'CSharpCodeProvider' nie używa nowego kompilatora z 6 [/langversion](https://msdn.microsoft.com/en-us/library/6ds95cz0(v=vs.140).aspx) –

+0

Autor kopiowanie folderu "roslyn" do miejsca, w którym było to oczekiwane - udało mi się to sprawić. Wygląda jednak na włamanie. Nie wiem, czy to błąd w miejscu kopiowania plików, czy błąd w miejscu, w którym szuka kompilatora. – Derek

+0

@Leonid Vasilyev, Widziałem to niedawno, ale nie pamiętam, gdzie ... przepraszam. –

19

kompilacja Run-time przy użyciu C# 6 możliwości wymaga nowego kompilatora, jak @ Thomas-Levesque wymienione. Ten kompilator można zainstalować przy użyciu pakietu nuget Microsoft.CodeDom.Providers.DotNetCompilerPlatform.

W przypadku aplikacji komputerowych wystąpił problem. ASP.NET zespół, w ich nieskończonej mądrości zostały zakodowane ścieżkę do kompilatora jako <runtime-directory>\bin\roslyn\csc.exe patrz dyskusja w https://github.com/dotnet/roslyn/issues/9483

Jeśli aplikacja jest kompilowany do \myapp\app.exe, kompilator Roslyn będzie zlokalizowany na \myapp\roslyn\csc.exe, ALE CSharpCodeProvider rozwiąże csc.exe jak \myapp\bin\roslyn\csc.exe

o ile mogę powiedzieć, masz dwie opcje

  1. Tworzenie post-build i/lub procedury instalacji, które będą przenieś podkatalog \roslyn do \bin\roslyn.
  2. Napraw kod runtime poprzez odbicie czarnej magii.

Oto nr 2, ujawniając CSharpCodeProvider jako właściwość w klasie narzędzia.

using System.Reflection; 
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform; 

static Lazy<CSharpCodeProvider> CodeProvider { get; } = new Lazy<CSharpCodeProvider>(() => { 
    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; 
}); 
+1

Dziękuję bardzo! To naprawiło mój problem :) –

+0

Używając tego hacka, pamiętaj, aby użyć wersji 1.0.5 lub wcześniejszej z pakietu NuGet Microsoft.CodeDom.Providers.DotNetCompilerPlatform. – Mustafa

+0

Dlaczego, czy oni naprawili coś? –