如何在MSBuild目标中重新运行属性评估? [英] How to re-run property evaluation in MSBuild target?

查看:89
本文介绍了如何在MSBuild目标中重新运行属性评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的MSBuild目标,部分代码片段如下..

I have a custom MSBuild target, partial snippet as follows ..

<Target Name="PublishHtm">
  <PropertyGroup>
    <PublishHtmTemplateContents>$([System.IO.File]::ReadAllText($(PublishHtmTemplatePath)))</PublishHtmTemplateContents>
    <PublishHtm>$(PublishHtmTemplateContents)</PublishHtm>
  </PropertyGroup>
  <WriteLinesToFile Lines="$(PublishHtm)" File="$(PublishDir)\publish.htm" Overwrite="true"/>
</Target>

这是对此解决方案的重做尝试,因为我正在尝试将此模板隔离到外部文件.该模板包含MSBuild属性引用,例如$(ApplicationName).完全按照链接的解决方案中的说明进行操作时,它可以正常工作,但是在将模板作为字符串加载时,没有效果这些属性表达式中的所有属性表达式都是根据到达文件的时间计算的.

This is a rework attempt for this solution in that I'm trying to isolate this template to an external file. The template contains MSBuild property references such as $(ApplicationName). When doing this exactly as described in the linked solution, it works fine, but when loading the template in as a string, none of these property expressions are evaluated by the time it gets to the file.

<SPAN CLASS="BannerTextApplication">$(ApplicationName)</SPAN>

给定目标被调用的上下文,是否可以使用MSBuild表达式/函数重新获得字符串?

Is there an MSBuild expression/function I can use to get the string to be reevaluated given the context that the Target is being invoked?

顺便说一句,我宁愿使用查找/替换或正则表达式替换来解决该问题,并坚持使用MSBuild表达式引擎.

BTW I'd rather not work around the problem using find/replace or regex replace, and stick with the MSBuild expression engine.

使用Visual Studio 2012& .NET Framework 4.5.

Using Visual Studio 2012 & .NET Framework 4.5.

推荐答案

抱歉,暂时没有回到这个问题. 最初,我认为要解决此问题,我们需要以非常不寻常的方式弯曲MSBuild(今天的计划是编写复杂的内联任务,该任务将使用Msbuild属性作为标记在外部文件中进行正则表达式替换).但是我认为使用CDATA部分可以更轻松地解决此问题,该部分在属性定义内有效:

Sorry for not getting back to this question for awhile. Initially I thought that to solve this problem we'll need to bend MSBuild in very unusual way (plan for today was to write complex inline task which will do regex-replace in external file using Msbuild properties as tokens ). But I think this can be solved easier, using CDATA section, which is valid inside property definition:

这是主脚本:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <PropertyGroup>
        <MyOtherProperty>$([System.DateTime]::Now)</MyOtherProperty>
        <Version>1.0.1b</Version>
        <ProjectName>MSBuild Rox</ProjectName>
        <Author>Alexey Shcherbak</Author>
    </PropertyGroup>

    <Target Name="Build">
        <ItemGroup>
            <PropsToPass Include="MyOtherProperty=$(MyOtherProperty)" />
            <PropsToPass Include="Version=$(Version)" />
            <PropsToPass Include="ProjectName=$(ProjectName)" />
            <PropsToPass Include="Author=$(Author)" />
        </ItemGroup>

        <MSBuild Projects="TransformHTML.Template.proj" Properties="@(PropsToPass)" />
    </Target>
</Project>  

这是您的模板.它不是纯html,它仍然是msbuild文件,但至少没有对xml中的html标签进行难看的编码.只是CDATA中的一个块

And here is your template. It's not pure html, it's still msbuild file, but at least without ugly encoding for html tags in xml. It's just a block in CDATA

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Transform">
    <PropertyGroup>
            <HtmlProperty><![CDATA[
                <body>
                    <div>$(MyOtherProperty)</div>
                    <div>$(Version)</div>
                    <div>$(ProjectName)</div>
                    <div>$(Author)</div>
                </body>
            ]]></HtmlProperty>
        </PropertyGroup>

    <Target Name="Transform">
        <Message Text="HtmlProperty: $(HtmlProperty)" Importance="High" />
    </Target>
</Project>  

也许它不是很优雅(我个人不喜欢带有@PropsToPass的部分),但可以完成工作.您可以将所有内容内联到单个文件中,然后无需将属性传递给MSBuild任务.我不喜欢提议的此解决方案"中的大量html编码,但我宁愿将HTML模板保留在将要转换的同一脚本中,只是以漂亮的html格式进行,而无需编码.

Maybe it's not very elegant ( I personally don't like the section with @PropsToPass) but it'll do the job. You can put everything inline into single file and then you don't need to pass properties to MSBuild task. I don't like massive html-encoding from proposed "this solution" but I'd rather prefer to keep HTML template in the same script where it'll be transformed, just in nice html format, without encoding.

单个文件示例:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
    <PropertyGroup>
        <MyOtherProperty>$([System.DateTime]::Now)</MyOtherProperty>
        <Version>1.0.1b</Version>
        <ProjectName>MSBuild Rox</ProjectName>
        <Author>Alexey Shcherbak</Author>
    </PropertyGroup>

    <Target Name="Build">
        <PropertyGroup>
            <HtmlProperty><![CDATA[
                <body>
                    <div>$(MyOtherProperty)</div>
                    <div>$(Version)</div>
                    <div>$(ProjectName)</div>
                    <div>$(Author)</div>
                </body>
            ]]></HtmlProperty>
        </PropertyGroup>

        <Message Text="HtmlProperty: $(HtmlProperty)" Importance="High" />
    </Target>
</Project>  

您还可以在此处下载这些文件

这篇关于如何在MSBuild目标中重新运行属性评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆