2015-09-24 14 views
19

C# 6.0'ı CSharpCodeProvider ile derleyemediğinizi ve Roslyn ile uğraşmayacağınızı okudum. Ancak bir dosyayı nasıl yükleyeceğimi ve daha sonra bir dll'ye nasıl derleyeceğimi iyi bir örnek bulamıyorum.Roslyn ile C# dosyası program aracılığıyla nasıl derlenir?

Bu kodla benzer bir şeyi Roslyn ile nasıl yazmalıyım? Yoksa bunu yapmanın başka bir yolu var mı? Ben C# 6.0 koduyla projelerine başvuru içeren dosyaları derlemeye çalıştığınızda Şimdi sadece "(bir derleme referans eksik?) Tipi veya ad alanı adı 'x' ad 'y' de yok" demek

bu yüzden daha sonra yükleyebilirsiniz bir dll bunu derleme

  • Yük C# dosya
  • : Özetle
    public string CompileCode() 
        { 
         var provider = new CSharpCodeProvider(); 
         var outputPath = Path.Combine(Path.GetDirectoryName(_path), $"Code.dll"); 
         var compilerparams = new CompilerParameters(_referencedAssemblies, outputPath); 
         CompilerResults results = provider.CompileAssemblyFromFile(compilerparams, _path); 
         var dllPath = results.PathToAssembly; 
         if (!results.Errors.HasErrors) 
          return dllPath; 
         PrintError(results.Errors); 
         return ""; 
        } 
    

    Ben istiyorum.

+0

Benzer konuyla ilgili başka bir yazı: [C# kodunu program aracılığıyla derlemeye ve yürütmeye çalışıyorum] (https://stackoverflow.com/q/10314815/4975230) – jrh

cevap

21

Çalışmanız için bir örnek oluşturdum. CSharp6 sürümünün size uygun olmasını sağlamak için .Net 4.6 için çalışma süresini kullanmak üzere ayarlamalısınız. Derlemelerin seçeneklerini seçebilmek için çok az ayrıntı ekledim. Gerekli

Değişiklikler - Aşağıdaki örnekte .Net 4.6 değiştirin LanguageVersion.Csharp6 için LanguageVersion.Csharp5 hedef çalışma zamanı yolunu değiştirin .

class Program 
    { 
     private static readonly IEnumerable<string> DefaultNamespaces = 
      new[] 
      { 
       "System", 
       "System.IO", 
       "System.Net", 
       "System.Linq", 
       "System.Text", 
       "System.Text.RegularExpressions", 
       "System.Collections.Generic" 
      }; 

     private static string runtimePath = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\{0}.dll"; 

     private static readonly IEnumerable<MetadataReference> DefaultReferences = 
      new[] 
      { 
       MetadataReference.CreateFromFile(string.Format(runtimePath, "mscorlib")), 
       MetadataReference.CreateFromFile(string.Format(runtimePath, "System")), 
       MetadataReference.CreateFromFile(string.Format(runtimePath, "System.Core")) 
      }; 

     private static readonly CSharpCompilationOptions DefaultCompilationOptions = 
      new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) 
        .WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release) 
        .WithUsings(DefaultNamespaces); 

     public static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null) 
     { 
      var stringText = SourceText.From(text, Encoding.UTF8); 
      return SyntaxFactory.ParseSyntaxTree(stringText, options, filename); 
     } 

     static void Main(string[] args) 
     { 
      var fileToCompile = @"C:\Users\DesktopHome\Documents\Visual Studio 2013\Projects\ConsoleForEverything\SignalR_Everything\Program.cs"; 
      var source = File.ReadAllText(fileToCompile); 
      var parsedSyntaxTree = Parse(source, "", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5)); 

      var compilation 
       = CSharpCompilation.Create("Test.dll", new SyntaxTree[] { parsedSyntaxTree }, DefaultReferences, DefaultCompilationOptions); 
      try 
      { 
       var result = compilation.Emit(@"c:\temp\Test.dll"); 

       Console.WriteLine(result.Success ? "Sucess!!" : "Failed"); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex); 
      } 
      Console.Read(); 
     } 

Bu, küçük ince ayarlara gerek duyar, ancak istediğiniz sonuçları vermelidir. İstediğiniz gibi değiştirin.

+0

Bu, mükemmel bir şekilde çalıştı, teşekkürler! – user1776562

+0

Bunu işe almak için hangi referanslara/paketlere ihtiyacım var? Teşekkürler. –

+1

Microsoft.CodeAnalysis.CSharp bu paket de diğer bağımlılıklar kuracaktır. – vendettamit

8

NuGet paketi Microsoft.CodeAnalysis.CSharp'u kullanmanız gerekir.

var syntaxTree = CSharpSyntaxTree.ParseText(source); 

CSharpCompilation compilation = CSharpCompilation.Create(
    "assemblyName", 
    new[] { syntaxTree }, 
    new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, 
    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); 

using (var dllStream = new MemoryStream()) 
using (var pdbStream = new MemoryStream()) 
{ 
    var emitResult = compilation.Emit(dllStream, pdbStream); 
    if (!emitResult.Success) 
    { 
     // emitResult.Diagnostics 
    } 
} 
İlgili konular