首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Roslyn以编程方式编译C#文件?

如何使用Roslyn以编程方式编译C#文件?
EN

Stack Overflow用户
提问于 2015-09-25 03:42:08
回答 2查看 20.5K关注 0票数 37

我读到你不能用CSharpCodeProvider编译C# 6.0,因此尝试用Roslyn6.0。但是我找不到一个好的例子来加载一个文件,然后把它编译成一个dll。

我应该如何使用Roslyn编写类似于此代码的代码?还是有其他方法可以做到这一点呢?现在,当我尝试使用C# 6.0代码编译包含对项目的引用的文件时,它只会说“类型或名称空间名称'x‘在名称空间'y’中不存在(您是否缺少程序集引用?)”

代码语言:javascript
复制
    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 ""; 
    }

总而言之,我想:

  • 加载C#文件
  • 将其编译为动态链接库以便我以后可以加载它。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-25 05:09:34

我已经创建了一个示例供您使用。您需要调整它以使用.Net 4.6的运行时,以便您可以使用CSharp6版本。我已经添加了一些细节,以便您可以选择编译的选项。

需要更改-将运行时路径更改为目标.Net 4.6,将以下示例中的LanguageVersion.Csharp5更改为LanguageVersion.Csharp6

代码语言:javascript
复制
 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();
        }

这将需要一些小的调整,但它应该会给你想要的结果。如您所愿,更改它。

票数 36
EN

Stack Overflow用户

发布于 2015-09-25 04:38:14

您必须使用NuGet包Microsoft.CodeAnalysis.CSharp

代码语言:javascript
复制
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
    }
}
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32769630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档