MSbuild,如何在内联任务代码中访问项目属性值?

6

我有一些用C#编写的内联任务代码

我想知道有没有什么办法可以在内联任务代码中访问属性

例如,我正在尝试使用项目属性值替换字符串匹配。这是否可能?

<![CDATA[
      MatchCollection matches = Regex.Matches(SourceStr, Pattern);

      for (int i = 0; i < matches.Count; i++)
           // replace the match value with project property... possible?


    ]]>
3个回答

5
像您在编译任务中那样,将其作为参数传递即可?
<ParameterGroup>
    <Foo ParameterType="System.Bar" Required="true" />
<ParameterGroup>

编辑:看起来简单的行内标记也可以工作。

<![CDATA[
    Console.WriteLine("$(Foo)");
]]>

附加背景:内联标记之所以有效,是因为 MSBuild 在编译任务之前替换了它们的值。 - riQQ

2

因为太大了,无法作为评论回复。

原因与您的另一个问题相同——评估顺序。代码在到达目标之前被评估和标记化,我假设那是您设置值并设置属性的地方。

如果我理解您尝试完成任务的目标,请看下面的示例,只需将它们作为属性传递并作为输出输出。

话虽如此,我认为您应该首先研究属性函数,这样可以省去很多麻烦。

http://msdn.microsoft.com/en-us/library/dd633440.aspx

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="Foo" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <SourceStr Required="true" Output="true" />
            <Pattern Required="true" />
            <Value Required="true" />
            <Macros ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
        </ParameterGroup>
        <Task>
            <Using Namespace="System.Linq" />
            <Using Namespace="System.Text.RegularExpressions" />
            <Code Type="Fragment" Language="cs">
            <![CDATA[
                var regex = new Regex(Pattern);
                var matches = regex.Matches(SourceStr).Cast<Match>().Select(m => m.Value).ToList();
                matches.ForEach(m => Log.LogMessage("{0} -> {1}", m, Value));
                Macros = matches.Select(m => new TaskItem(m)).ToArray();
                SourceStr = regex.Replace(SourceStr, Value);
            ]]>
            </Code>
        </Task>
    </UsingTask>
    <Target Name="Foo">
        <PropertyGroup>
            <SourceStr>Bar</SourceStr>
            <Value>z</Value>
        </PropertyGroup>
        <Message Text="in $(SourceStr)" />
        <Foo SourceStr="$(SourceStr)" Pattern="r$" Value="$(Value)">
            <Output TaskParameter="SourceStr" PropertyName="SourceStr" />
            <Output TaskParameter="Macros" ItemName="Macros" />
        </Foo>
        <Message Text="out $(SourceStr)" />
        <Message Text="sans %(Macros.Identity)" />
    </Target>
</Project>

嗯...我无法将它作为参数传递的原因是'value'。 - in His Steps
值在找到“匹配项”之前是未知的。 值是在搜索模式时决定的,因为我想替换多个不同的字符串模式... - in His Steps

0

MSDN文档中有一些示例。例如:

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="4.0">
    <UsingTask TaskName="TokenReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <Path ParameterType="System.String" Required="true" />
            <Token ParameterType="System.String" Required="true" />
            <Replacement ParameterType="System.String" Required="true" />
        </ParameterGroup>
        <Task>
            <Code Type="Fragment" Language="cs">
                <![CDATA[
    string content = File.ReadAllText(Path);
    content = content.Replace(Token, Replacement);
    File.WriteAllText(Path, content);
    ]]>
            </Code>
        </Task>
    </UsingTask>

    <Target Name='Demo' >
        <TokenReplace Path="C:\Project\Target.config" Token="$MyToken$" Replacement="MyValue"/>
    </Target>
</Project>

如果$(MyValue)是一个项目属性,你可以这样做:
<TokenReplace Path="C:\Project\Target.config" Token="$MyToken$" Replacement="$(MyValue)"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接