首页 > 解决方案 > Roslyn 无法与 .net Framework Console 应用程序和 Docker 一起正常工作

问题描述

我们有一个问题,即通过 CSharpCodeProvider 执行的简单 c# 代码在运行本地命令行和 docker 时的工作方式不同。

代码示例如下,在 Roslyn 上运行时它不会返回任何类型的程序集,但在本地运行良好。我真的不知道如何从这里调试它 - 欢迎任何帮助!

using System;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
using System.IO;
using System.Reflection;
using System.Text;
using System.CodeDom.Compiler;

namespace TestContainerIssue
{
  class Program
  {
    static void Main(string[] args)
    {

      using (var codeProvider = new CSharpCodeProvider())
      {
        var compilerParameters = new CompilerParameters
        {
          GenerateExecutable = false,
          GenerateInMemory = true
        };
        compilerParameters.CompilerOptions = String.Format("/lib:\"{0}\"", Path.GetDirectoryName(Uri.UnescapeDataString((new UriBuilder(Assembly.GetExecutingAssembly().CodeBase)).Path)));
        Console.WriteLine(compilerParameters.CompilerOptions);
        compilerParameters.ReferencedAssemblies.Add("System.dll");
        compilerParameters.ReferencedAssemblies.Add("System.Core.dll");

        CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, ExecutionWrapperCode);
        if (compilerResults.Errors.HasErrors)
        {
          StringBuilder errors = new StringBuilder();
          foreach (CompilerError error in compilerResults.Errors)
            errors.AppendLine(error.ErrorText);
          throw new Exception(errors.ToString());
        }
        Console.WriteLine(compilerResults.PathToAssembly);
        Assembly assembly = compilerResults.CompiledAssembly;
        Console.WriteLine(assembly.FullName);
        Console.WriteLine("Types:");
        foreach (Type t in assembly.GetTypes())
        {
          Console.WriteLine(t);
        }

        Type type = assembly.GetType("Validation.Execution");
        Console.WriteLine("Type:");
        Console.WriteLine(type);  //Empty when run in Docker (both mcr.microsoft.com/windows:1909 and mcr.microsoft.com/windows/servercore:ltsc2019

        var methodInfo = type.GetMethod("Execute");
        Console.WriteLine(methodInfo);
      }
    }

    private const string ExecutionWrapperCode = @"
using System;

namespace Validation
{
  public static class Execution
  {
    public static string Execute()
    {
      return ""test"";
    }
  }
}";

  }
}

我尝试了以下 docker 文件(我尝试了两个 Windows 映像:mcr.microsoft.com/windows:1909 和 mcr.microsoft.com/windows/servercore:ltsc2019

FROM mcr.microsoft.com/windows/servercore:ltsc2019
ADD /bin/Debug /
ENTRYPOINT TestContainerIssue.exe

编辑:我构建了这两个 dll,并在 dotPeek 中对它们进行了比较——你可以看到 Docker 中的那个缺少命名空间。它们的字节长度完全相同。

在此处输入图像描述

标签: c#dockerroslyndocker-for-windows

解决方案


原来这行代码:

        compilerParameters.CompilerOptions = String.Format("/lib:\"{0}\"", Path.GetDirectoryName(Uri.UnescapeDataString((new UriBuilder(Assembly.GetExecutingAssembly().CodeBase)).Path)));

导致了这个问题。我不知道它为什么会导致它并且不会在编译器中引发错误,但也许会对其他人有所帮助。曾是


推荐阅读