系统相关
首页 > 系统相关> > c# – Roslyn – CodeDom:HowTo动态编译Code到Universal-Windows-Library

c# – Roslyn – CodeDom:HowTo动态编译Code到Universal-Windows-Library

作者:互联网

我正在生成一个动态包含WPF项目包装类的.NET Dll.我正在使用System.CodeDom.Compiler.CodeDomProvider类.

现在我必须为Universal-Windows-Dll创建一个包装类.
由于System.CodeDom.Compiler.CodeDomProvider类仍然使用旧的.NET编译器,我不得不切换到新的Roslyn编译器(通过添加Nuget包Microsoft.CodeDom.Providers.DotNetCompilerPlatform).
然后我用新的CSharpCodeProvider替换了code-dom-Provider的实例化.

new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();

Code编译得很好,但我发现无法设置TargetFramework / CompilerVersion.
旧的CodeDomProvider有CompilerOptions,我可以在其中指定CompilerVersion等.但是新的Roslyn没有这个选项(或者我找到它是愚蠢的).

结果是它将DLL编译为普通的.NET 4.x Dll.但我需要一个Universal-Windows Dll,因为它用于Universal-Project.

浏览互联网我发现了许多使用Roslyn编译器的不同方法.它们中的大多数似乎来自编译器的旧Beta版本,因此它们都不起作用.
Roslyn.Compilers命名空间(在大多数示例中使用)似乎是来自beta的命名空间.

有人知道如何正确使用roslyn编译器吗?
我不想修改编译器.我只想通过从SourceCode编译动态生成DLL,但我必须指定平台目标.

解决方法:

可以选择引用编译器和运行时版本.最新版本的Roslyn具有此新功能,您可以指定要使用的目标框架以及要使用的编译器版本.

我也在四处寻找最新的Roslyn库来编译一个CSharp6版程序来编译4.6框架.以下是我的工作样本.

注意,在Parser中指向.Net框架库和CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6)选项的runtimepath变量.

 public 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.6\{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.WindowsRuntimeApplication)
                    .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);
        }

        public static void Main(string[] args)
        {
            //ReferenceFinder finder = new ReferenceFinder();
            //finder.Find("Read");

            var fileToCompile = @"C:\Users\..\Documents\Visual Studio 2013\Projects\SignalR_Everything\Program.cs";
            var source = File.ReadAllText(fileToCompile);
            var parsedSyntaxTree = Parse(source, "", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6));

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

标签:c,dll,roslyn,win-universal-app,codedom
来源: https://codeday.me/bug/20190623/1271939.html