我正在尝试学习如何使用Roslyn从c#源文件中提取信息。但我甚至无法开始,因为我似乎无法找到正确的方法来安装正确的软件包。
我正在尝试构建一个简单的netcoreapp1.1控制台应用。它的csproj文件如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PackageTargetFallback>portable-net45+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.0.0" />
<PackageReference Include="Microsoft.Composition" Version="1.0.30" />
</ItemGroup>
</Project>
我从在线阅读中看到,这足以加载任何包含MSBuildWorkspace的程序集......但显然不是。
如何正确配置项目?
答案 0 :(得分:2)
不幸的是,MSBuildWorkspace
is currently only supported on .Net Framework。您将无法从.Net Core中使用它。
答案 1 :(得分:1)
接受的答案似乎不再是最新的:存在一个支持.NET的 NuGet包 Microsoft.CodeAnalysis.Workspaces.MSBuild 核心控制台应用程序:
使用以下代码行尝试该软件包:
using Microsoft.CodeAnalysis.MSBuild;
...
var workspace = MSBuildWorkspace.Create();
var solution = workspace.OpenSolutionAsync(solutionFile.FullName).Result;
...它引发了异常。我发现有一个帖子(https://github.com/dotnet/roslyn/issues/17401#issuecomment-282605950),其中添加了其他一些似乎是依赖项的NuGet程序包。那在我的csproj中做了引用:
<PackageReference Include="Microsoft.Build" Version="16.7.0" />
<PackageReference Include="Microsoft.Build.Framework" Version="16.7.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.7.0" />
,有了这些参考,我就可以使用它了(我在Windows上工作)。
但是,我遇到了一个问题,即Microsoft.CodeAnalysis.Project的文档计数为0,而someProject.GetCompilationAsync()。Result.SyntaxTrees为空。未正确设置“ MSBUILD_EXE_PATH”(请参见https://github.com/dotnet/roslyn/issues/22415)。首先,我选择以这种方式设置最新的MSBuild.dll:
private static void SetMSBuildPath()
{
var latestSdk = new DirectoryInfo(@"C:\Program Files\dotnet\sdk\").EnumerateDirectories().Where(f => Regex.IsMatch(f.Name, @"\d+\.\d+\.\d+"))
.OrderByDescending(f => f.Name.Split(".")[0])
.ThenByDescending(f => f.Name.Split(".")[1])
.ThenByDescending(f => f.Name.Split(".")[2])
.FirstOrDefault();
Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", Path.Combine(latestSdk.FullName, "MSBuild.dll"));
}
但是更好的方法是使用NuGet包Microsoft.Build.Locator,并在应用程序的开头调用它,如下所示:
MSBuildLocator.RegisterDefaults();
要执行此操作,请确保按照documentation的建议将MSBuild排除在您使用的Microsoft.Build.*
NuGet软件包(Microsoft.Build.Locator
除外)之外(这会更改上面显示的PackageReferences ):
<PackageReference Include="Microsoft.Build" Version="16.7.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" Version="16.7.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.7.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.7.0" />
PS:我没有研究过,但是也许https://github.com/daveaglick/Buildalyzer(NuGet软件包“ Buildalyzer”)解决了所有这些问题。