2015-09-24 12 views
19

मैंने पढ़ा है कि आप सीएस 6.0 को CSharpCodeProvider के साथ संकलित नहीं कर सकते हैं और Roslyn के साथ करने का प्रयास करने के लिए। लेकिन मुझे एक अच्छा उदाहरण नहीं मिल रहा है कि फ़ाइल कैसे लोड करें और फिर इसे एक डीएलएल में संकलित करें।Roslyn प्रोग्रामेटिक रूप से एक सी # फ़ाइल संकलित कैसे करें?

मुझे रोज़लिन के साथ इस कोड के समान कुछ कैसे लिखना चाहिए? या क्या ऐसा करने का कोई और तरीका है? अब जब मैं उन फ़ाइलों को संकलित करने का प्रयास करता हूं जिनमें सी # 6.0 कोड वाली परियोजनाओं के संदर्भ शामिल हैं, तो बस "टाइप या नेमस्पेस नाम 'x' नामस्थान 'वाई' में मौजूद नहीं है (क्या आप एक असेंबली संदर्भ खो रहे हैं?)"

इसलिए मैं इसे बाद में लोड कर सकते हैं

  • लोड एक सी # फ़ाइल
  • यह एक dll को संकलित करें:
    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 ""; 
        } 
    

    सारांश में मैं चाहता हूँ।

+0

एक ही विषय पर एक और पोस्ट: [प्रोग्रामिंग रूप से सी # कोड संकलित करने और निष्पादित करने की कोशिश कर रहा है] (https://stackoverflow.com/q/10314815/4975230) – jrh

उत्तर

21

मैंने आपके साथ काम करने के लिए एक नमूना बनाया है। आपको नेट 4.6 के लिए रन टाइम का उपयोग करने के लिए इसे ट्विक करने की आवश्यकता है ताकि CSharp6 संस्करण आपके लिए उपलब्ध हो। मैंने थोड़ा विवरण जोड़ा है ताकि आप संकलन के विकल्प चुन सकें।

परिवर्तन की आवश्यकता - नीचे दिए नमूने में नेट 4.6 बदलें LanguageVersion.Csharp6 को LanguageVersion.Csharp5 को लक्षित करने के क्रम के मार्ग को परिवर्तित करें।

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(); 
     } 

इसे छोटे बदलावों की आवश्यकता होगी लेकिन इसे आपको वांछित परिणाम देना चाहिए। जैसा चाहें इसे बदलें।

+0

यह पूरी तरह से काम करता है, धन्यवाद! – user1776562

+0

क्या आप मुझे बता सकते हैं कि मुझे यह काम करने के लिए क्या संदर्भ/पैकेज चाहिए? धन्यवाद। –

+1

माइक्रोसॉफ्ट.कोडएनालिसिस .CSharp यह पैकेज अन्य निर्भरताओं को भी स्थापित करेगा। – vendettamit

8

आपको NuGet पैकेज Microsoft.CodeAnalysis.CSharp का उपयोग करना होगा।

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 
    } 
} 
संबंधित मुद्दे