Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Roslyn编译.net核心应用程序时出错_C#_.net Core_Roslyn - Fatal编程技术网

C# 使用Roslyn编译.net核心应用程序时出错

C# 使用Roslyn编译.net核心应用程序时出错,c#,.net-core,roslyn,C#,.net Core,Roslyn,我正在生成代码,然后使用Roslyn进行编译。对于框架来说,它工作得很好,但当我尝试对核心做同样的事情时,它失败了 错误是: 程序集中类型“System.Func`2”的类型转发器 “System.Runtime”导致循环 以下是失败的代码: using System; using System.Collections.Generic; using System.Linq; using System.Data; namespace CoreTest { public class Te

我正在生成代码,然后使用Roslyn进行编译。对于框架来说,它工作得很好,但当我尝试对核心做同样的事情时,它失败了

错误是:

程序集中类型“System.Func`2”的类型转发器 “System.Runtime”导致循环

以下是失败的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;

namespace CoreTest
{

    public class TestCore
    {
        public void Test()
        {
            var dt = new DataTable();
            dt.Columns.Add("A");

            var numbers = new List<int>();
            var items = numbers.Where(q => q > 5).ToList();
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统数据;
命名空间核心测试
{
公共类TestCore
{
公开无效测试()
{
var dt=新数据表();
dt.列。添加(“A”);
变量编号=新列表();
var items=numbers.Where(q=>q>5.ToList();
}
}
}
下面是编译它的代码:

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;

namespace CompilerTest
{

    public class BuildCodeCore
    {
        private string _CoreAssemblyFolder = @"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1";

        public BuildCodeCore() { }

        public List<string> Files { get; set; } = new List<string>();
        public string OutputFileNameAndPath { get; set; }
        public string ReferencedAssembliesPath { get; set; }

        public void BuildCore()
        {
            string assemblyFolder = _CoreAssemblyFolder;
            string coreAssemblyFileName = "System.Runtime.dll";

            var assemblies = GetAssembliesInFolder(assemblyFolder);
            if (!string.IsNullOrWhiteSpace(ReferencedAssembliesPath))
            {
                assemblies.AddRange(GetAssembliesInFolder(ReferencedAssembliesPath));
            }

            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            ICodeCompiler icc = codeProvider.CreateCompiler();

            CompilerParameters parameters = new CompilerParameters();
            parameters.CoreAssemblyFileName = coreAssemblyFileName;
            parameters.ReferencedAssemblies.AddRange(assemblies.ToArray());
            parameters.GenerateExecutable = false;
            parameters.OutputAssembly = OutputFileNameAndPath;

            CompilerResults results = icc.CompileAssemblyFromFileBatch(parameters, Files.ToArray());

            if (results.Errors.Count > 0)
            {
                foreach (CompilerError error in results.Errors)
                {
                    Console.WriteLine(error);
                }
            }

        }

        private List<string> GetAssembliesInFolder(string assemblyPath)
        {
            var files = Directory.GetFiles(assemblyPath, "*.dll");

            return files.ToList();
        }

    }
}
使用系统;
使用System.CodeDom.Compiler;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
命名空间编译器测试
{
公共类BuildCodeCore
{
私有字符串\u CoreSassemblyFolder=@“C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1”;
公共BuildCodeCore(){}
公共列表文件{get;set;}=new List();
公共字符串OutputFileName和路径{get;set;}
公共字符串ReferenceAssembliesPath{get;set;}
public void BuildCore()
{
字符串assemblyFolder=\u CoreSassemblyFolder;
字符串CoreSassemblyFileName=“System.Runtime.dll”;
var assemblies=GetAssembliesInFolder(assemblyFolder);
如果(!string.IsNullOrWhiteSpace(referenceAssembliesPath))
{
AddRange(GetAssembliesInFolder(referenceAssembliesPath));
}
CSharpCodeProvider codeProvider=新的CSharpCodeProvider();
ICodeCompiler icc=codeProvider.CreateCompiler();
CompilerParameters参数=新的CompilerParameters();
parameters.CoreSemblyFileName=CoreSemblyFileName;
parameters.referencedAssemblys.AddRange(assemblies.ToArray());
parameters.GenerateExecutable=false;
parameters.OutputAssembly=OutputFileName和Path;
CompilerResults results=icc.compileasemblyfromfilebatch(参数,Files.ToArray());
如果(results.Errors.Count>0)
{
foreach(结果中的编译器错误。错误)
{
控制台写入线(错误);
}
}
}
私有列表GetAssembliesInFolder(字符串assemblyPath)
{
var files=Directory.GetFiles(assemblyPath,*.dll);
返回files.ToList();
}
}
}
我指的是核心dll的NuGetFallbackFolder文件夹和nuget中的其他dll,
System.Data.DataSetExtensions.dll
System.Data.SqlClient.dll
都是Visual Studio中工作项目中的文件夹

如果我注释掉两个DataTable行并使用System.Data,它就会工作。 如果我把数字和项目行注释掉,它就行了


我在这里遗漏了什么?

事实证明,CompileAsemblyFromFileBatch不适用于核心应用程序

我不得不切换到使用csharp编译和Emit方法。这适用于编译框架和核心

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace CompilerTest
{
    public class BuildEmit
    {
        private string _CoreAssemblyFolder = @"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1";
        private string _FrameworkAssemblyFolder = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2";

        public BuildEmit() { }

        public List<string> Files { get; set; } = new List<string>();
        public string OutputFileNameAndPath { get; set; }
        public string ReferencedAssembliesPath { get; set; }
        public CompilerType Compiler { get; set; }


        public void Build()
        {
            string assemblyFolder = string.Empty;
            string coreAssemblyFileName = string.Empty;
            switch (Compiler)
            {
                case CompilerType.Framework:
                    assemblyFolder = _FrameworkAssemblyFolder;
                    coreAssemblyFileName = "mscorlib.dll";
                    break;
                case CompilerType.Core:
                    assemblyFolder = _CoreAssemblyFolder;
                    coreAssemblyFileName = "System.Runtime.dll";
                    break;
            }
            PortableExecutableReference objectDef = MetadataReference.CreateFromFile(Path.Combine(assemblyFolder, coreAssemblyFileName));

            List<SyntaxTree> syntaxes = new List<SyntaxTree>();
            foreach (string codeFile in Files)
            {
                var code = File.ReadAllText(codeFile);
                var tree = CSharpSyntaxTree.ParseText(code);
                syntaxes.Add(tree);
            }

            var references = new List<PortableExecutableReference>();
            references.Add(objectDef);

            var assemblies = FilterInvalidAssembies(GetAssembliesInFolder(assemblyFolder));
            if (!string.IsNullOrWhiteSpace(ReferencedAssembliesPath))
            {
                assemblies.AddRange(GetAssembliesInFolder(ReferencedAssembliesPath));
            }
            foreach (string item in assemblies)
            {
                var reference = MetadataReference.CreateFromFile(item);
                references.Add(reference);
            }
            var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(OutputFileNameAndPath), syntaxes, references);
            compilation = compilation.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var emitResult = compilation.Emit(OutputFileNameAndPath);

            if (!emitResult.Success)
            {
                foreach (var diagnostic in emitResult.Diagnostics)
                {
                    Console.WriteLine(diagnostic.ToString());
                }
                File.Delete(OutputFileNameAndPath);
            }
        }

        private void RemoveStringFromList(List<string> items, string contains)
        {
            var item = items.Where(q => q.Contains(contains)).Select(q => q).FirstOrDefault();
            if (item != null)
            {
                items.Remove(item);
            }
        }

        private List<string> FilterInvalidAssembies(List<string> files)
        {
            RemoveStringFromList(files, "System.EnterpriseServices.Wrapper.dll");
            RemoveStringFromList(files, "System.EnterpriseServices.Thunk.dll");
            //RemoveStringFromList(files, "mscorlib.dll");
            return files;
        }

        private List<string> GetAssembliesInFolder(string assemblyPath)
        {
            var files = Directory.GetFiles(assemblyPath, "*.dll");

            return files.ToList();
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.CSharp;
命名空间编译器测试
{
公共类BuildEmit
{
私有字符串\u CoreSassemblyFolder=@“C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1”;
私有字符串\u FrameworkAssemblyFolder=@“C:\Program Files(x86)\Reference Assemblys\Microsoft\Framework\.NETFramework\v4.6.2”;
公共BuildEmit(){}
公共列表文件{get;set;}=new List();
公共字符串OutputFileName和路径{get;set;}
公共字符串ReferenceAssembliesPath{get;set;}
公共编译器类型编译器{get;set;}
公共void Build()
{
string assemblyFolder=string.Empty;
string CoreSassemblyFileName=string.Empty;
开关(编译器)
{
案例编译器类型。框架:
assemblyFolder=\u FrameworkAssemblyFolder;
CoreSassemblyFileName=“mscorlib.dll”;
打破
案例编译器类型.Core:
assemblyFolder=\u CoreSassemblyFolder;
CoreSassemblyFileName=“System.Runtime.dll”;
打破
}
PortableExecutableReference objectDef=MetadataReference.CreateFromFile(Path.Combine(assemblyFolder,CoreSassemblyFileName));
列表语法=新列表();
foreach(文件中的字符串代码文件)
{
var code=File.ReadAllText(代码文件);
var tree=CSharpSyntaxTree.ParseText(代码);
语法。添加(树);
}
var references=新列表();
添加(objectDef);
var assemblies=FilterInvalidAssembies(GetAssembliesInFolder(assemblyFolder));
如果(!string.IsNullOrWhiteSpace(referenceAssembliesPath))
{
AddRange(GetAssembliesInFolder(referenceAssembliesPath));
}
foreach(程序集中的字符串项)
{
var reference=MetadataReference.CreateFromFile(项);
参考文献。添加(参考文献);
}
var compilation=csharpcomilation.Create(Path.GetFileNameWithoutExtension(OutputFileNameAndPath)、语法、引用);
compilation=compilation.WithOptions(新的CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
var emitResult=compilation.Emit(OutputFileN