gpt4 book ai didi

visual-studio-2013 - 使用 Microsoft.Build.Evaluation 解析实际引用路径

转载 作者:行者123 更新时间:2023-12-04 19:03:13 24 4
gpt4 key购买 nike

我正在使用小型 C# 控制台应用程序中的 Microsoft.Build.Evaluation 工具对 csproj 文件进行一些自省(introspection)和分析。我想定位引用项目的实际位置,使用与 MSBuild 本身相同的启发式方法,即描述的位置 here .我正朝着将构建工件自动转换为包的方向前进,类似于 JetBrains 博客 here 中概述的内容

我能找到的唯一示例期望 HintPath 是正确的,例如 this project ,而且我知道有些 HintPaths 目前不正确,我不想相信它们。这个项目非常接近我想要做的事情,增加了我想使用真正的解析行为来查找依赖项的复杂性。

我的 csproj 有一个 Microsoft.Build.Evaluation.Project 对象的实例,但我看不到任何可用的方法可以为我提高分辨率。我想我希望的是一个用于 Reference 或 ProjectItem 的神奇 Resolve() 方法,有点像 this method .

我可能可以通过将自己的搜索限制在此构建系统使用的一组有限输出路径来找到替代方案,但如果可以的话,我想挂接到 MSBuild。

最佳答案

引用解析是 MSBuild 中最棘手的部分之一。如何定位程序集的逻辑在一组标准任务中实现:
ResolveAssemblyReference , ResolveNativeReference等等。逻辑是它的工作原理非常复杂,您只需查看这些任务的可能参数数量即可看出这一点。

但是,您不需要知道查找引用文件位置的确切逻辑。有称为“ResolveAssemblyReferences”、“ResolveProjectReferences”的标准目标和其他一些更专门用于 native 引用、COM 引用的目标。这些目标作为正常构建的一部分执行。如果你只是单独执行这些目标,你可以找出返回值,这正是你所需要的。 IDE 使用相同的机制来获取引用的位置,用于 Intellisense、内省(introspection)等。

以下是如何在代码中执行此操作:

using Microsoft.Build.BuildEngine;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using System;
using System.Collections.Generic;

class Program
{
static int Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Usage: GetReferences.exe <projectFileName>");
return -1;
}

string projectFileName = args[0];

ConsoleLogger logger = new ConsoleLogger(LoggerVerbosity.Normal);
BuildManager manager = BuildManager.DefaultBuildManager;

ProjectInstance projectInstance = new ProjectInstance(projectFileName);
var result = manager.Build(
new BuildParameters()
{
DetailedSummary = true,
Loggers = new List<ILogger>() { logger }
},
new BuildRequestData(projectInstance, new string[]
{
"ResolveProjectReferences",
"ResolveAssemblyReferences"
}));

PrintResultItems(result, "ResolveProjectReferences");
PrintResultItems(result, "ResolveAssemblyReferences");

return 0;
}

private static void PrintResultItems(BuildResult result, string targetName)
{
var buildResult = result.ResultsByTarget[targetName];
var buildResultItems = buildResult.Items;

if (buildResultItems.Length == 0)
{
Console.WriteLine("No refereces detected in target {0}.", targetName);
return;
}

foreach (var item in buildResultItems)
{
Console.WriteLine("{0} reference: {1}", targetName, item.ItemSpec);
}
}
}

请注意,调用引擎是为了调用项目中的特定目标。您的项目通常不会构建,但某些目标可能会被先决条件目标调用。

只需编译它并打印所有依赖项的子集。如果您对项目使用 COM 引用或 native 依赖项,​​则可能会有更多依赖项。应该很容易修改样本以获取这些样本。

关于visual-studio-2013 - 使用 Microsoft.Build.Evaluation 解析实际引用路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31759821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com