首页 > 解决方案 > 在 Roslyn 中解析程序集引用

问题描述

我正在为 C# 项目编写元数据提取器。它的工作原理是通过SyntaxTrees从源文件创建,通过CSharpSyntaxTree.ParseText()编译它们CSharpCompilation.Create(),然后分析SemanticModel.

我遇到了一个问题,即没有正确处理各种程序集引用。

我通过解析project.assets.json和提取编译时包引用来生成程序集引用(我的测试项目不包括任何项目引用)。的目标部分project.assets.json如下所示:

"targets": {
".NETStandard,Version=v2.1": {
  "Autofac/5.1.2": {
    "type": "package",
    "compile": {
      "lib/netstandard2.1/Autofac.dll": {}
    },
    "runtime": {
      "lib/netstandard2.1/Autofac.dll": {}
    }
  },
  "Microsoft.NETCore.Platforms/1.1.0": {
    "type": "package",
    "compile": {
      "lib/netstandard1.0/_._": {}
    },
    "runtime": {
      "lib/netstandard1.0/_._": {}
    }
  },
  "Microsoft.NETCore.Targets/1.1.0": {
    "type": "package",
    "compile": {
      "lib/netstandard1.0/_._": {}
    },
    "runtime": {
      "lib/netstandard1.0/_._": {}
    }
  },
  "Serilog/2.9.0": {
    "type": "package",
    "compile": {
      "lib/netstandard2.0/Serilog.dll": {}
    },
    "runtime": {
      "lib/netstandard2.0/Serilog.dll": {}
    }
  },
  "Serilog.Sinks.Console/3.1.1": {
    "type": "package",
    "dependencies": {
      "Serilog": "2.5.0",
      "System.Console": "4.3.0"
    },
    "compile": {
      "lib/netstandard1.3/Serilog.Sinks.Console.dll": {}
    },
    "runtime": {
      "lib/netstandard1.3/Serilog.Sinks.Console.dll": {}
    }
  },
  "Serilog.Sinks.File/4.1.0": {
    "type": "package",
    "dependencies": {
      "Serilog": "2.5.0",
      "System.IO.FileSystem": "4.0.1",
      "System.Text.Encoding.Extensions": "4.0.11",
      "System.Threading.Timer": "4.0.1"
    },
    "compile": {
      "lib/netstandard2.0/Serilog.Sinks.File.dll": {}
    },
    "runtime": {
      "lib/netstandard2.0/Serilog.Sinks.File.dll": {}
    }
  },
  "System.Console/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.IO": "4.3.0",
      "System.Runtime": "4.3.0",
      "System.Text.Encoding": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Console.dll": {}
    }
  },
  "System.IO/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0",
      "System.Text.Encoding": "4.3.0",
      "System.Threading.Tasks": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.5/System.IO.dll": {}
    }
  },
  "System.IO.FileSystem/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.IO": "4.1.0",
      "System.IO.FileSystem.Primitives": "4.0.1",
      "System.Runtime": "4.1.0",
      "System.Runtime.Handles": "4.0.1",
      "System.Text.Encoding": "4.0.11",
      "System.Threading.Tasks": "4.0.11"
    },
    "compile": {
      "ref/netstandard1.3/System.IO.FileSystem.dll": {}
    }
  },
  "System.IO.FileSystem.Primitives/4.0.1": {
    "type": "package",
    "dependencies": {
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
    },
    "runtime": {
      "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
    }
  },
  "System.Runtime/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0"
    },
    "compile": {
      "ref/netstandard1.5/System.Runtime.dll": {}
    }
  },
  "System.Runtime.Handles/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Runtime.Handles.dll": {}
    }
  },
  "System.Text.Encoding/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Text.Encoding.dll": {}
    }
  },
  "System.Text.Encoding.Extensions/4.0.11": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0",
      "System.Text.Encoding": "4.0.11"
    },
    "compile": {
      "ref/netstandard1.3/System.Text.Encoding.Extensions.dll": {}
    }
  },
  "System.Threading.Tasks/4.3.0": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.1.0",
      "Microsoft.NETCore.Targets": "1.1.0",
      "System.Runtime": "4.3.0"
    },
    "compile": {
      "ref/netstandard1.3/System.Threading.Tasks.dll": {}
    }
  },
  "System.Threading.Timer/4.0.1": {
    "type": "package",
    "dependencies": {
      "Microsoft.NETCore.Platforms": "1.0.1",
      "Microsoft.NETCore.Targets": "1.0.1",
      "System.Runtime": "4.1.0"
    },
    "compile": {
      "ref/netstandard1.2/System.Threading.Timer.dll": {}
    }
  }
}
}

结果引用列表如下:

lib/netstandard2.1/Autofac.dll
lib/netstandard1.0/_._
lib/netstandard1.0/_._
lib/netstandard2.0/Serilog.dll
lib/netstandard1.3/Serilog.Sinks.Console.dll
lib/netstandard2.0/Serilog.Sinks.File.dll
ref/netstandard1.3/System.Console.dll
ref/netstandard1.5/System.IO.dll
ref/netstandard1.3/System.IO.FileSystem.dll
ref/netstandard1.3/System.IO.FileSystem.Primitives.dll
ref/netstandard1.5/System.Runtime.dll
ref/netstandard1.3/System.Runtime.Handles.dll
ref/netstandard1.3/System.Text.Encoding.dll
ref/netstandard1.3/System.Text.Encoding.Extensions.dll
ref/netstandard1.3/System.Threading.Tasks.dll
ref/netstandard1.2/System.Threading.Timer.dll

我忽略了两个格式奇怪的 netstandard1.0 ,将它们替换为由 创建的引用MetadataReference.CreateFromFile( Assembly.Load( "netstandard" ).Location ) ),并针对本地 nuget 存储库解析剩余路径,从 dll 创建引用。

这大部分工作正常......但某些事情没有解决。以下是我在编译后收到的诊断消息CSharpCompilation.Create()

CS0103 - 当前上下文中不存在名称“Assembly”

CS0103 - 当前上下文中不存在名称“路径”

CS1069 - 在命名空间“System”中找不到类型名称“ApplicationException”。此类型已转发到程序集 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 考虑添加对该程序集的引用。SymbolExtractor::AnalyzeProject

CS0103 - 当前上下文中不存在名称“环境”

有趣的是,所有这些错误都与我正在尝试编译的项目中的静态类中的一种方法有关。我不确定它是否相关,但这是有问题的代码:

public static string DefineLocalAppDataLogPath( string fileStub, string folder = null )
{
    fileStub = IsFileNameValid( fileStub ) ? fileStub : "log.txt";

    if( string.IsNullOrEmpty( folder ) )
    {
        var assLoc = Assembly.GetExecutingAssembly().GetType().Assembly.Location;
            folder = Path.GetFileNameWithoutExtension( assLoc );
    }

    DirectoryInfo logDir = null;

    if( ( logDir = CreateLogFileDirectory( folder ) ) == null )
    {
        if( ( logDir = CreateLogFileDirectory( "LogFiles" ) ) == null )
            throw new ApplicationException(
                $"Couldn't create log file directory {folder} or the backup/default directory 'LogFiles'" );
    }

    return logDir.FullName;
}

关于解决程序集依赖关系,我缺少什么?我是否还需要包括对运行时所需的程序集的引用?

标签: c#roslyn-code-analysismicrosoft.codeanalysis

解决方案


推荐阅读