Can't get MSBuild Community Task RegexReplace

2019-05-13 20:24发布

问题:

I'm trying to copy a bunch of files whose names begin with the prefix DR__, but the copies must have that prefix removed. That is, DR__foo must be copied as foo. I'm trying this, which is based in the example provided in the documentation (the .chm):

<Target Name="CopyAuxiliaryFiles">
    <MakeDir Directories="$(TargetDir)Parameters" Condition="!Exists('$(TargetDir)Parameters')" />
    <ItemGroup>
      <ContextVisionParameterFiles Include="$(SolutionDir)CVParameters\DR__*" />
    </ItemGroup>
    <Message Text="Files to copy and rename: @(ContextVisionParameterFiles)"/>
    <RegexReplace Input="@(ContextVisionParametersFiles)" Expression="DR__" Replacement="">
      <Output ItemName ="DestinationFullPath" TaskParameter="Output" />
    </RegexReplace>
    <Message Text="Renamed Files: @(DestinationFullPath)"/>
    <Copy SourceFiles="@(ContextVisionParameterFiles)" DestinationFiles="@(DestinationFullPath)" />
  </Target>

DestinationFullPath comes out empty (or that's what I see when I display it with Message). Thus, Copy fails because no DestinationFiles are specified. What's wrong here?

Edit: ContextVisionParameterFiles is not empty, it contains this:

D:\SVN.DRA.WorkingCopy\CVParameters\DR__big_bone.alut;D:\SVN.DRA.WorkingCopy\CVParameters\DR__big_medium.gop

They're actually 40 files, but I trimmed it for the sake of clarity

回答1:

Got it! It seems to have been the combination of a stupid error and a seemingly compulsory parameter. As for the first one, there were two Targets called CopyAuxiliaryFiles. As for the second one, it seems the Count parameter is needed.

The final, working version:

<Target Name="CopyCvParameters">
    <ItemGroup>
      <CvParamFiles Include="$(SolutionDir)CVParameters\DR__*" />
    </ItemGroup>
    <Message Text="Input:&#xA;@(CvParamFiles, '&#xA;')"/>
    <!-- Replaces first occurance of "foo." with empty string-->
    <RegexReplace Input="@(CvParamFiles)" Expression="^.*DR__" Replacement="$(TargetDir)Parameters\" Count="1">
      <Output ItemName ="RenamedCvParamFiles" TaskParameter="Output" />
    </RegexReplace>
    <Message Text="&#xA;Output RenamedCvParamFiles:&#xA;@(RenamedCvParamFiles, '&#xA;')" />
    <Copy SourceFiles="@(CvParamFiles)" DestinationFiles="@(RenamedCvParamFiles)" SkipUnchangedFiles="True" />
  </Target>

Notice that:

  • I renamed the Target to solve the name collision (Why doesn't Visual Studio detect this as an error?)
  • I pretty-printed the ItemGroups with the @(CvParamFiles, '&#xA;') syntax, which seems to replace ; with line breaks
  • My regex replaces the absolute path and the prefix
  • Count="1" is now passed to RegexReplace