当前位置:  开发笔记 > 编程语言 > 正文

如何查询MSBUILD文件以获取支持的目标列表?

如何解决《如何查询MSBUILD文件以获取支持的目标列表?》经验,为你挑选了3个好方法。

有没有办法问msbuild什么构建目标提供msbuild文件支持?如果在命令提示符下无法执行此操作?可能是以编程方式完成的吗?

除了解析msbuild XML之外,还有办法吗?



1> Zac Thompson..:

当然,MS提供了api,无需自己解析xml.查找microsoft.build.buildengine

改编自msdn上的一些C#代码 ...通常值得探索.需要引用microsoft.build.engine dll才能进行编译.用您的值替换下面的框架版本和路径.这适用于示例项目文件,尽管列表可能比您预期的要长.

using System;
using Microsoft.Build.BuildEngine;
class MyTargets
{        
  static void Main(string[] args)
  {
    Engine.GlobalEngine.BinPath = @"C:\Windows\Microsoft.NET\Framework\v2.0.NNNNN";
    Project project = new Project();
    project.Load(@"c:\path\to\my\project.proj");
    foreach (Target target in project.Targets)
    {
      Console.WriteLine("{0}", target.Name);
    }
  }
}


我的下一个问题是,*为什么在地狱中我们必须写一个程序来做这个?*

2> Jaykul..:

我喜欢使用PowerShell的想法,但纯XML解决方案不起作用,因为它只输出在项目文件中定义的目标,而不是导入.当然,每个人一直指的C#代码都很简单,而.Net 4.5则是两行(首先你应该考虑添加到你的个人资料中):

Add-Type -As Microsoft.Build
New-Object Microsoft.Build.Evaluation.Project $Project | Select -Expand Targets 

是啊.真.这就是全部.

由于输出非常详细,您可能希望限制您正在查看的内容:

New-Object Microsoft.Build.Evaluation.Project $Project | 
    Select -Expand Targets |
    Format-Table Name, DependsOnTargets -Wrap

然而,有一个问题.

当您加载这样的构建时,GlobalProjectCollection只要您将PowerShell窗口保持打开状态,它们就会一直存在,并且在卸载它们之前无法重新打开它们.要卸载它们:

[Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.UnloadAllProjects()

考虑到这一点,在一个可以接受部分和相对路径甚至管道项目文件作为输入的函数中包装它可能是值得的:

Add-Type -As Microsoft.Build
Update-TypeData -DefaultDisplayPropertySet Name, DependsOnTargets -TypeName Microsoft.Build.Execution.ProjectTargetInstance

function Get-Target {
    param(
        # Path to project file (supports pipeline input and wildcards)
        [Parameter(ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=1)]
        [Alias("PSPath")]
        [String]$Project,

        # Filter targets by name. Supports wildcards
        [Parameter(Position=2)]
        [String]$Name = "*"

    )
    begin {
        # People do funny things with parameters
        # Lets make sure they didn't pass a Project file as the name ;)
        if(-not $Project -and $Name -ne "*") {
            $Project = Resolve-Path $Name
            if($Project) { $Name = "*" }
        }
        if(-not $Project) {
            $Project = Get-Item *.*proj
        }
    }
    process {
        Write-Host "Project: $_ Target: $Name"
        Resolve-Path $Project | % {
            # Unroll the ReadOnlyDictionary to get the values so we can filter ...
            (New-Object Microsoft.Build.Evaluation.Project "$_").Targets.Values.GetEnumerator()
        } | Where { $_.Name -like $Name }
    }
    end {
        [microsoft.build.evaluation.projectcollection]::globalprojectcollection.UnloadAllProjects()
    }
}

而现在你甚至不需要手动格式表...

附录:

显然,您可以使用Update-TypeData向输出添加任何内容,例如,如果您想查看条件,或者可能是BeforeTargets或AfterTargets ......

你甚至可以提取嵌套信息.例如,您可以Update-TypeData使用以下两个替换上面的调用:

Update-TypeData -MemberName CallTargets -MemberType ScriptProperty -Value {
    $this.Children | ? Name -eq "CallTarget" | %{ $_.Parameters["Targets"] } 
} -TypeName Microsoft.Build.Execution.ProjectTargetInstance

Update-TypeData -DefaultDisplayPropertySet Name, DependsOnTargets, CallTargets -TypeName Microsoft.Build.Execution.ProjectTargetInstance

你看到第一个添加了一个计算的CallTargets属性,它枚举直接子节点并查找CallTarget任务来打印它们的目标,然后我们只包括那个ind DefaultDisplayPropertySet.

注意:在构建任何特定目标时,要查看将要执行的每个目标需要很多逻辑(为此,我们必须递归处理DependsOnTargets,我们还需要查找在他们的 BeforeTargets或AfterTargets中(也是递归地)具有此目标的任何目标,并且在我们到达实际上只能调用目标的任务之前,例如CallTargets MSBuild ......并且所有这些事情都可能依赖于如此复杂的条件没有实际执行它就不可能知道会发生什么;)



3> 小智..:

已针对.NET Framework 4进行了更新,因为上述内容已被弃用.导入microsoft.build.dll和代码如下:

using System;
using Microsoft.Build.Evaluation;
class MyTargets
{
  static void Main(string[] args)
  {
    Project project = new Project(args[0]);
    foreach (string target in project.Targets.Keys)
    {
      Console.WriteLine("{0}", target);
    }
  }
}


我的下一个问题是,*为什么在地狱中我们必须写一个程序来做这个?*
@jww动态可扩展性.诅咒和礼物同时.尽管如此,它会带来更多痛苦的泪水.
推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有